Curious
Curious

Reputation: 21530

How to tell the maximum data alignment requirement in C++

Referencing this question and answer Memory alignment : how to use alignof / alignas? "Alignment is a restriction on which memory positions a value's first byte can be stored." Is there a portable way in C++ to find out the highest granularity of alignment that is required for instructions not to fault (for example in ARM)? Is alignof(intmax_t) sufficient since its the largest integer primitive type?

Further, how does something in malloc align data to a struct's boundaries? For example if I have a struct like so

alignas(16) struct SomethingElse { ... };

the SomethingElse struct is required to be aligned to a boundary that is a multiple of 16 bytes. Now if I request memory for a struct from malloc like so

SomethingElse* ptr = malloc(sizeof(SomethingElse));

Then what happens when malloc returns a pointer that points to an address like 40? Is that invalid since the pointer to SomethingElse objects must be a multiple of 16?

Upvotes: 2

Views: 1270

Answers (2)

eerorika
eerorika

Reputation: 238401

How to tell the maximum data alignment requirement in C++

There is std::max_align_t which

is a POD type whose alignment requirement is at least as strict (as large) as that of every scalar type.

Vector instructions may use array operands that require a higher alignment than any scalar. I don't know if there is a portable way to find out the the upper bound for that.

To find the alignment requirement for a particular type, you can use alignof.


Further, how does something in malloc align data to a struct's boundaries?

malloc aligns to some boundary that is enough for any scalar. In practice exactly the same as std::max_align_t.

It won't align correctly for "overaligned" types. By overaligned, I mean a type that has higher alignment requirement than std::max_align_t.

Then what happens when malloc returns a pointer that points to an address like 40?

Dereferencing such SomethingElse* would be have undefined behaviour.

Is that invalid since the pointer to SomethingElse objects must be a multiple of 16?

Yes.


how even would one go about fixing that? There is no way to tell malloc the alignment that you want right?

To allocate memory for overaligned types, you need std::aligned_alloc which is to be introduced in C++17.

Until then, you can use platform specific functions like posix_memalign or you can over allocate with std::malloc (allocate the alignment - 1 worth of extra bytes), then use std::align to find the correct boundary. But then you must keep track of both the start of the buffer, and the start of the memory block separately.

Upvotes: 3

Igor Tandetnik
Igor Tandetnik

Reputation: 52611

You might be looking for std::max_align_t

Upvotes: 2

Related Questions