Often malloc is used to allocate memory for n elements of some primitive datatype (int, float, char). This could look like this:
#define N 10
double *mem = malloc(N * sizeof(double));
for (int i = 0; i < N; ++i) {
mem[i] = 10.0; // Write
double d = mem[i]; // Read
}
This would even work if I declared mem as char * and used a cast later on:
char *mem = malloc(N * sizeof(double));
for (int i = 0; i < N; ++i) {
*(double*)(mem + i * sizeof(double)) = 10.0;
double d = *(double *)(mem + i * sizeof(double));
}
Currently I'm wondering if this is well defined and working for every datatype (even any complex type like struct). Lets assume struct a could be anything. Is the following well defined?
char *mem = malloc(N * sizeof(struct a));
for (int i = 0; i < 10; ++i)) {
*(struct a *)(mem + i * sizeof(struct a)) = /* something valid */;
struct a x = *(struct a *)(mem + i * sizeof(struct a));
}
Since the return value of malloc is suitably aligned for any kind of variable the case i = 0 is definitely well defined and working, but how about I = 1, 2, ...? Will alignment screw this up? Like in this example:
char char_arr[4] = /* some value */;
int *d = &char_arr[0];
The second line is not guaranteed to work, since char_arr may not be aligned on a 4-byte boundary (required for int).
malloc.sizeofoperator takes care right, since its including the padding?sizeofwill returns the full size of the structure, including padding.mallocparts become "problematic" (actually UB, too) if you access the allocated block via thechar *, then cast to another type. Why don't you use the correct type for the pointer? Whychar *?malloc& friends returnvoid *, notchar *.char *is not " capable to hold any kind of data". Casts from anychar *to another type pointer can be UB. Your question was about pointer frommalloc(). The higher level coding goal remains unclear. Knowing that may provide even better answers.