The ISO C90 Standard (or at least the draft of it that I have) says this about malloc
and alignment:
The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object and then used to access such an object or an array of such objects in the space allocated...
But can you use the same pointer returned by malloc
for two different types? For example, suppose that I know that sizeof(int) <= 2 * sizeof(short)
. Could I allocate enough memory for 5
short
s, and use the first two as an int
, i.e. is the following code guaranteed to work as intended?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
void* data = malloc(5 * sizeof(short));
short* short_array = data;
int* int_ptr = data;
if (!data) return EXIT_FAILURE;
*int_ptr = 13943;
short_array += 2; /* Skip over the int */
short_array[0] = 7;
short_array[1] = 238;
short_array[2] = -123;
printf("%d %d %d %d\n", *int_ptr, short_array[0], short_array[1], short_array[2]);
free(data);
return 0;
}
I've tried this code, and it does output 13943 7 238 -123
for me, but I'm not entirely sure if it's standard-compliant.
Edit: Specifically, I'm trying to make a dynamic array type (which can be an array of any type), so I'm allocating an array of one type, and using the start of that allocation as a pointer to a header which contains the length and capacity of the array.
To be clear, here is approximately what I'm doing:
size_t header_elements = (sizeof(ArrayHeader) + array_type_size - 1) / array_type_size); /* = ceil(sizeof(ArrayHeader) / array_type_size) */
void* data = malloc((header_elements + array_length) * array_type_size);
ArrayHeader* header = data;
void* array = (char*)data + header_elements * array_type_size;
So, header
points to the start of the allocation and the actual array
is offset by a multiple of the size of the type stored in it.