Take the 2-minute tour ×

If new[] expression is used to create an array of objects having destructors, the objects in the array may not be properly alligned

#include <stdint.h>
#include <stdio.h>

#pragma pack(8)
struct A{
  int64_t i;
  char dummy;

int main(){
  A* pa= new A[2];
  printf("sizeof(A)= %d, pointer= %p", sizeof(A), pa);

(I build 32-bit target with VC++ 2010 express)

The output (on my computer) is:

 sizeof(A)= 16 pointer= 00344f4c

(sizeof(A)= 16 shows that compiler undrstand the alignment requirements for A and the struct is padded with 7 bytes [ edited: __alignof(A) also returns 8 ])

I understand why it happens: new[] needs to store array length and it use for this purpose first 4 bytes of allocated memory, then it allocates the array itself without proper padding.

From a practical viewpoint such a behaviour is definitely poor, but is it standard compliant or not?

share|improve this question
That's unbelievable. Even our in-house custom implementation of operator new respects alignment. –  sharptooth Jan 28 '11 at 11:30
isn't this the result of your #pragma pack(8) still in effect in your main ? –  Adrien Plisson Jan 28 '11 at 11:44
@sharptooth custom operator new simply allocates memory which is used by compiler to generate code for new expression. Allocated memory is always properly aligned, but objects are placed by compiler to wrong place inside this memory –  user396672 Jan 28 '11 at 11:45
@Adrien Plisson sizof(A)==16 shows that pragma pack take effect –  user396672 Jan 28 '11 at 11:47
Th standard grantees alignment of the returned result. I doubt that Visual Studio is broken. So your hypothesis must be incorrect. I don't understand why you think it is not aligned. –  Loki Astari Jan 28 '11 at 11:48
show 5 more comments

8 Answers

up vote 4 down vote accepted

You should use __declspec for this purpose. Your code generated misaligned objects on my computer too (using VS2010) but when I changed to __declspec(align(8)), the pointers were correctly aligned.

I believe that pragma pack only changes the size of the struct and doesn't make any guarantees about it's location.

share|improve this answer
This worked for me too. Strangely, __alignof(A) gave 8 even without the __declspec. –  interjay Jan 28 '11 at 12:11
yes - if i understand msdn.microsoft.com/en-us/library/83ythb65%28v=vs.80%29.aspx correctly, the #pragma pack effects only the alignment inside the struct (e.g. the relative offset of each member to each other). __declspec(align(8)) does both, which is what you want. –  Tobias Langner Jan 28 '11 at 12:12
Indeed, it works! But why pragma and project settings have no effect? –  user396672 Jan 28 '11 at 12:14
@user396672: If my answer solved your problem, mark it as accepted. pragma pack only affects the packing of the struct, i.e., only aligns the size of the struct, not it's memory locations. –  Puppy Jan 28 '11 at 12:18
@ DeadMG I've marked :) it seems also that /ZpX project setting simply defaults implicit pragma value, and doesn't affect code generation and runtime –  user396672 Jan 28 '11 at 12:28
add comment

The standard guarantees that the memory is correctly aligned.

I doubt that Visual Studio got something so basic wrong.

Currently I don't follow why you think it is not aligned?

Are you trying to suggest it should be aligned to 16 byte boundaries?
That is not required by the standard. It may only need to align to 4 byte boundaries.

3.11 Alignment [basic.align]


Thus the following code should print out the maximum required alignment of the implementation:

#include <iostream>
#include <cstddef>
#include <cstdalign>

int main()
        std::cout << alignof(std::max_align_t) << "\n";
share|improve this answer
The struct in the question contains a 64-bit member variable, so the address should be 8-bytes aligned. –  sharptooth Jan 28 '11 at 11:58
It must be aligned to 8 byte boundary. MS compiler adds 7-byte padding to the struct, therefore, it understands 8-byte requirement imposed by member type, #pragma pack (and default alignment too) –  user396672 Jan 28 '11 at 11:58
@sharptooth: @user396672: That is not a requirement of the standard. –  Loki Astari Jan 28 '11 at 12:11
@Martin York: That's strange. Why does our custom allocator ensure 8-bytes alignment then... –  sharptooth Jan 28 '11 at 12:12
@sharptooth: No idea, but on x86, if you're not allocating SSE types, you don't need 8byte alignment. Of course, if you're working with some other low-level technology like CUDA you may need more alignment, and if you want relatively easy porting to x64, 8byte alignment isn't a bad idea. –  Puppy Jan 28 '11 at 12:17
show 5 more comments

Well to answer your question literally I don't think the standard says anything about #pragma pack at all. So I would say that your code has undefined behavour according to the standard.

share|improve this answer
I also tried __alignof(A), it returns 8. If we can treat MS's __alignof as replacement for standard alignof(A), then fundamental alignment for type A is 8 and must be respected by compiler –  user396672 Jan 28 '11 at 13:22
add comment

Interesting. My first question would be: what happens without the #pragma pack? What is the native alignement for this struct. The operator new has no means of knowing what options you might have set with the pragma, so its presence or absense has no effect here. And formally, there's no violation of the standard, since Intel doesn't require any alignment for anything (but maintaining proper alignment sure helps performance). All in all, it doesn't seem like a desirable "feature", but it's a QoI issue, and not a standard conformance one.

share|improve this answer
without pragma there is exactly the same result. Project default alignment is 8, __alignof(A) returns 8. If __alignof(A) actually returns the alignment of A (otherwise, what it returns?) then new must return properly aligned pointer, but it doesn't. But formally speaking, ms-specific __align may return anything :). I suppose, it was a bug that MS doesn't fix due to compatability problems. Perhaps, some placement new[] invokations in old applications may not reserve enough extra space. And they have fixed the bug by introducing special declspec, not by default (it is only my hypothesis) –  user396672 Jan 31 '11 at 9:33
add comment

IIRC the default packing is on byte alignment, use /Zpn to set to another packing, then you get your padding. (or #pragma pack(n) )

EDIT: come to think about I think the default packing even varies between VS versions

share|improve this answer
default packing in project settings is also 8 bytes /Zp8 –  user396672 Jan 28 '11 at 11:51
add comment
 printf("sizeof(A)= %d, pointer= %08x", sizeof(A), pa);

As a token of caution, use %p when you want to print memory address:


%x expects unsigned int whose size may be different from the size of a pointer.

share|improve this answer
I've edited the post, thank you :) –  user396672 Jan 28 '11 at 11:40
... and %zu for size_t values. –  unwind Jan 28 '11 at 11:41
...... @unwind: sorry, but msvc++ doesn't support %z :) –  user396672 Jan 28 '11 at 13:24
add comment

If struct A just contains plain old data, you can use aligned_malloc (see Microsoft's documentation). If it needs to be constructed, you can combine this with the placement new operator. Something like this (I don't have Microsoft VC++, so it might not compile):

void* buf = _aligned_malloc (2 * sizeof (struct A), 8) ;
A* pa = new (buf) A[2];

Deleting this is a pain: you have to call pa[i].~A() explicitly for each array element, and then _aligned_free (buf).

share|improve this answer
Indeed, there are a lot of possible workarounds :) –  user396672 Jan 28 '11 at 13:54
add comment

operator new() which keyword new calls under the hood, has no knowledge of type's alignment. The only alignment requirement is that operator new() has to allocate memory suitably aligned for a built-in type with the largest alignment requirement, which is often 8 on a 32-bit platform (the alignment requirement of double).

Having said that, the example you posted allocates memory aligned on 8-byte boundary as it should.

share|improve this answer
Have you actually read the question? It is about result of new[] expression, not about implementation of new[] operator (i.e.memory allocator) which (you are right) works properly. –  user396672 Jan 28 '11 at 12:45
add comment

Your Answer


