Is there a way to guarantee alignment of malloc () structure members - ed

I recently fixed a bug in which the __declspec(align(64)) member of the structure was offset due to how memory was allocated for the structure. So I'm looking for a way around these situations.

For example, consider the following structure:

 struct foo { __declspec(align(64)) int bar[BAZ_LEN]; int baz; }; 

If allocated on the stack, the compiler will follow the alignment. If allocated through malloc() , this will not work. This will break the code that accesses the bar if it depends on its alignment for reasons of performance or correctness (or both).

So the question is: what is the best way to deal with such situations? In my situation, struct foo can be considered opaque to all but the 'private' functions of my component.

Clarification / Update . Thanks so much for the answers. I should have said this in advance, but the problem was that the user of my structure allocated a piece of memory and cut it into several parts, and one of the middle ones was an array of foo_t structus. The offset to this array is not constant, so aligning the start address is unlikely to help. I am looking for a way to allow this use of my structures, while preserving some alignment prerequisites.

The solution I have in mind right now (have not tried) is to add an add-on element:

 struct foo { __declspec(align(64)) int bar[BAZ_LEN]; int baz; char padding[64]; }; 

And than in each function do the following (wrapped in a macro):

 void f(foo_t *foo_) { foo_t *foo = (foo_t *)(((uintptr_t)foo_ & ~63) + 64); ... } 

This sends 64 bytes to each structure, which is not a problem in my case. Since the pad element never opens, the shift does not cause any malfunctions. However, this solution adds quite a bit of mental overhead, since alignment must be sanitized for every public function ...

+6
source share
2 answers

In the C11 standard, you can use aligned_alloc() :

ISO / IEC 9899: 2011

7.22.3.1 aligned_alloc function

Summary

 #include <stdlib.h> void *aligned_alloc(size_t alignment, size_t size); 

Description
2 The aligned_alloc function allocates space for an object whose alignment is specified by alignment, the size of which is set by size and whose value is undefined. The alignment value must be the actual alignment supported by the implementation, and the size value must be integer multiples of the alignment.

Returns
3 The aligned_alloc function returns either a null pointer or a pointer to the allocated space.

Or you can use POSIX posix_memalign() :

NAME

posix_memalign - dedicated memory allocation (ADVANCED REALTIME)

SYNTAX

 #include <stdlib.h> int posix_memalign(void **memptr, size_t alignment, size_t size); [Option End] 

DESCRIPTION

The posix_memalign() function should allocate size bytes aligned to the border specified by alignment , and return a pointer to the allocated memory in memptr . The alignment value must be a power of two multiple of sizeof (void *).

After successful completion, the value pointed to by memptr must be a multiple of alignment.

If the size of the requested space is 0, the behavior is determined by the implementation; the value returned in memptr must be either a null pointer or a unique pointer.

The free () function frees the memory previously allocated by posix_memalign ().

RETURN VALUE

Upon successful completion, posix_memalign() returns zero; otherwise, the error number must be returned to indicate the error.

Note that there is no aligned_realloc() and the POSIX equivalent.

+6
source

You can use posix_memalign for dynamic alignment. C11 has a memory alignment control, for example. "Manage memory alignment" on this blog.

+4
source

All Articles