I'm a bit late to the party but i like some type safety on compile time, so:
void* _mallocInit(int type_size, int size, void* init_list) {
void* mem = malloc(size * type_size);
if (mem == NULL) return mem;
memcpy(mem, init_list, type_size * size);
return mem;
}
#define NUMARGS(actualType, ...) (sizeof((actualType[]){__VA_ARGS__})/sizeof(actualType))
#define mallocInit(actualType, ...)\
(actualType*)_mallocInit(sizeof(actualType), NUMARGS(actualType, __VA_ARGS__), (actualType[]){__VA_ARGS__})
And an example that warns on compile time:
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void* _mallocInit(int type_size, int size, void* init_list) {
void* mem = malloc(size * type_size);
if (mem == NULL) return mem;
memcpy(mem, init_list, type_size * size);
return mem;
}
#define NUMARGS(actualType, ...) (sizeof((actualType[]){__VA_ARGS__})/sizeof(actualType))
#define mallocInit(actualType, ...)\
(actualType*)_mallocInit(sizeof(actualType), NUMARGS(actualType, __VA_ARGS__), (actualType[]){__VA_ARGS__})
typedef struct {
uint32_t id;
char* smt;
} foo_t;
int main() {
// works if .smt=1 is replaced by .smt=NULL
foo_t *l = mallocInit(foo_t,{ .id=1, .smt=mallocInit(char, "opa") }, { .id=10, .smt=1 });
printf("%d %d\n", l[0].smt, l[1].smt );
free(l); // leaking .smt memory, deal with it
}
The warning is pretty good as well:
test.c: In function ‘main’:
test.c:28:87: warning: initialization of ‘char *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
28 | foo_t *l = mallocInit(foo_t,{ .id=1, .smt=mallocInit(char, "opa") }, { .id=10, .smt=1 });
| ^
*y = (SOME_DATA_TYPE[5]) {v1, v2, v3, v4, v5};
? – Kujawafree(y)
then crashes my application. – Hourix
: that is not an array! If it was an array, it would not be called "pointer". – Paritymemcpy(y, (SOME_DATA_TYPE[5]){v1, v2, v3, v4, v5}, sizeof(SOME_DATA_TYPE)*5);
... – Kujawa