Malloc and alignment

111 Views Asked by At

As far as I know, every type - like int - can only be stored at memory addresses which start at a power of 2. Now my question is, how can malloc cope with this requirement? For instance, if I call

void * ptr;
ptr = malloc(8);

Then it is not obvious what I want to store in the given memory block of eight bytes. Is it therefore true that malloc always returns a starting address of the block which is located the largest power of 2 such that every standard type could be stored? If I misunderstand something, please feel free to correct me.

2

There are 2 best solutions below

8
Eric Postpischil On BEST ANSWER

C 2018 7.22.3 specifies the behavior of the memory allocation routines and its paragraph 1 says “… The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement…”

6.2.8 2 says:

… The alignment requirements of the following types shall be fundamental alignments:

  • all atomic, qualified or unqualified basic types;

  • all atomic, qualified or unqualified enumerated types;

  • all atomic, qualified or unqualified pointer types;

  • all array types whose element type has a fundamental alignment requirement;

  • all types specified in Clause 7 as complete object types;

  • all structure or union types all of whose elements have types with fundamental alignment requirements and none of whose elements have an alignment specifier specifying an alignment that is not a fundamental alignment.

6.2.5 14 says:

The type char, the signed and unsigned integer types, and the floating types are collectively called the basic types.

3
Nierusek On

From man:

The malloc() and calloc() functions return a pointer to the allocated memory, which is suitably aligned for any built-in type.

So it will be aligned. I also want to add that you're mistaken that:

As far as I know, every type - like int - can only be stored at memory addresses which start at a power of 2.

Code below works fine on x86_64, but it will not work on ARM.

#include <stdio.h>


int main() {
    int a[3];
    a[0] = a[1] = a[2] = 0;
    int *b = 1 + (void *)&a[1];
    *b = 6;
    printf("%x %x %x", a[0], a[1], a[2]);
}

As you can see, the pointer is not aligned to 4 bytes, but it will work.