In this I need C++ array class template, which is fixed-size, stack-based and doesn't require default constructor answer I posted a piece of code, that is using placement new with char array. For me, this is something absolutely normal. But according to comments this code is wrong.
Can anyone explain in more detail?
Specifically what can go wrong with the array. What I understand from the comments is that T x[size]; might not fit into char x[size*sizeof(T)];. I don’t believe this is true.
EDIT:
I’m just more and more confused. I know what alignment is in case of structures. Yes, when you have a structure the attributes start on different offsets then you might think.
OK, now we are back to arrays. You are telling me that T x[size]; is the same size as char x[size*sizeof(T)];, yet I cannot access the char array as T array because there might be some alignment. How can there be alignment when the arrays have the same size?
EDIT 2:
OK I finally get it, it may start on a wrong address.
EDIT 3:
Thx everyone, you can stop posting 🙂 Phew, this total blew my mind. I just never realized this was possible.
A
T x[size]array will always fit exactly intosize * sizeof(T)bytes, meaning thatchar buffer[size*sizeof(T)]is always precisely enough to store such an array.The problem in that answer, as I understood it, was that your
chararray is not guaranteed to be properly aligned for storing the object of typeT. Onlymalloc-ed/new-ed buffers are guaranteed to be aligned properly to store any standard data type of smaller or equal size (or data type composed of standard data types), but if you just explicitly declare achararray (as a local object or member subobject), there’s no such guarantee.Alignment means that on some platform it might be strictly (or not so strictly) required to allocate, say, all
intobjects on, say, a 4-byte boundary. E.g. you can place anintobject at the address0x1000or0x1004, but you cannot place anintobject at the address0x1001. Or, more precisely, you can, but any attempts to access this memory location as an object of typeintwill result in a crash.When you create an arbitrary
chararray, the compiler does not know what you are planning to use it for. It can decide to place that array at the address0x1001. For the above reason, a naive attempt to create anintarray in such an unaligned buffer will fail.The alignment requirements on some platform are strict, meaning that any attempts to work with misaligned data will result in run-time failure. On some other platforms they are less strict: the code will work, but the performance will suffer.
The need for the proper alignment sometimes means that when you want to create an
intarray in an arbitrarychararray, you might have to shift the beginning of anintarray forward from the beginning of thechararray. For example, if thechararray resides at0x1001, you have no choice but to start your constructed-in-placeintarray from the address0x1004(which is thecharelement with the index 3). In order to accommodate the tail portion of the shiftedintarray, thechararray would have to be 3 bytes larger than what thesize * sizeof(T)evaluates to. This is why the original size might not be enough.Generally, if your
chararray is not aligned in any way, you will really need an array ofsize * sizeof(T) + A - 1bytes to accommodate an aligned (i.e. possibly shifted) array of objects of typeTthat must be aligned at A-byte boundary.