Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manage memory alignments and generic pointer arithmetics in a portable way in C?

I have to implement an optimized version of malloc/realloc/free (tailored for my particular application). At the moment the code runs on a particular platform, but I would like to write it in a portable way, if possible (the platform may change in the future), or at least I would like to concentrate the possible platform differences in a single point (probably a .h). I am aware of some of the problems:

  • differences in memory alignment
  • differences in smallest memory blocks size suitable for "generic" allocation
  • differences in pointer size

(I'll ignore the differences in the basic system services for memory allocation here, since on some embedded systems they may be unavailable at all. Let's imagine that we work on a big preallocated memory block to be used as "heap").

The question(s):

  • Are there standard macros or functions in C for this kind of purpose?
  • What other issues may I face in this job?
like image 692
Giuseppe Guerrini Avatar asked Jan 23 '12 08:01

Giuseppe Guerrini


People also ask

Does malloc guarantee alignment?

Since malloc (or another dynamic memory allocator) is not necessarily guaranteed to align memory as we require, we'll need to perform two extra steps: Request extra bytes so we can returned an aligned address. Request extra bytes and store the offset between our original pointer and our aligned pointer.

What is pointer alignment?

Aligned Pointer means that pointer with adjacent memory location that can be accessed by a adding a constant and its multiples. for char a[5] = "12345"; here a is constant pointer if you and the size of char to it every time you can access the next chracter that is, a +sizeofchar will access 2.

Is malloc 16 byte aligned?

The GNU documentation states that malloc is aligned to 16 byte multiples on 64 bit systems.

Are all pointers the same size?

The type is important. While pointers are all the same size, as they just store a memory address, we have to know what kind of thing they are pointing TO.


2 Answers

The classic way to ensure that you maintain alignment suitable for all the basic types is to define a union:

union alloc_align {
    void *dummy1;
    long long dummy2;
    long double dummy3;
};

...then ensure that the addresses you hand out are always offset by a multiple of sizeof (union alloc_align) from the aligned addresses you recieve from the system memory allocator.

I believe a method similar to this is described in K&R.

like image 107
caf Avatar answered Nov 02 '22 13:11

caf


Alignment features are only handled in the new C standard, C11. It has keywords _Alignof, _Alignas and a function aligned_alloc. Theses features are not very difficult to emulate with most modern compilers (as indicated in other answers), so I'd suggest you write yourself small macros or wrappers that you'd use depending on __STDC_VERSION__.

like image 22
Jens Gustedt Avatar answered Nov 02 '22 14:11

Jens Gustedt