A std::vector<char> contains a pointer to some heap-allocated buffer.
Considering memory alignment issues, is the allocated buffer returned by the memory allocation guaranteed to be correctly aligned for only the type char, or will it be aligned to some common value, such as 4 or 8 bytes? (Or is it unspecified?)
To explain by way of example, the default allocator is new. Calling new may return an arbitrary memory address. But is it really arbitrary?
- Perhaps it is 8-byte aligned on 64 bit machines?
- Perhaps it is aligned for the type
Tused instd::vector<T>? (This seems the most likely of the options.) - Perhaps the returned address is arbitrary, and can have any value. (I don't think this is correct.)
- Something else?
The reason for asking this question is that I want to know whether I can safely re-interpret the bytes contained within this block of memory as other types, for example float, double, uint64_t, etc.
Going the other way, the situation is more obvious. (I think - do correct me.)
For example, if we were to ask for a std::vector<uint64_t>, then the pointer returned by the memory allocation, and held by the std::vector object, would be 8-byte aligned.
So it would be safe to read and write data as:
char*- Correctly aligned (4-byte aligned)
float - Correctly aligned (8-byte)
double - Correctly aligned (2-byte)
unsigned short int - ... etc
However, if the allocation for std::vector<char> can return a memory address of 1025 (decimal), then this is clearly not guaranteed to be aligned correctly at any offset if re-interpreted as any type larger than 1 byte wide.
I think my understanding is correct here, but of course do let me know in the comments if any of this doesn't quite make sense or fit together correctly.
Edit:
I may have found an answer to this, but I am not sure how to interpret what I have read.
From:
This function is required to return a pointer suitably aligned to point to an object of the requested size.
But what does this mean?
For an object of width 1 byte, this would seemingly suggest any address value is acceptable.
For an object of width 2 bytes, it would suggest any even value address is acceptable.
For 4 bytes, any multiple of 4. And for 8 bytes any multiple of 8.
But what about other values? There is no instruction to load a 3 byte value from memory in x86, as far as I am aware. What happens if you request new[T] where T is a 3 byte wide struct?
default_allocatoris built onnew [], therefore this answers your question: Does new char actually guarantee aligned memory for a class type?T, not for re-interpreting a pointer toTas a pointer to some other typeUnew char[]is sufficiently aligned for any object. It's literally the first line. All you need to know in addition is that the default allocator usesnew char[]under the hood. And that's what I just told you