2

Is this program ill-formed?

#include <new>

struct A
{
  int a;
  int b;
};

struct B
{
  int a;
};

int main()
{    
  void* p(operator new(sizeof(A)));
  new (p) A();
  static_cast<A*>(p)->~A();

  new (p) B();
  static_cast<B*>(p)->~B();

  operator delete(p);
}

Note that we have a guarantee that p will be correctly aligned for type A. But how about the type B? Does the standard mention anything? Is there a standard way to realign p?

EDIT: I feel the accepted answer needs more explanation. operator new must return a pointer correctly aligned for any object of that size, but of what type is that object going to be? It does not know (and alignment depends upon type), hence it must provide a pointer properly aligned for instances of all possible types and since a "smaller" type's maximum alignment is less than "bigger" type's, the pointer should be correctly aligned.

4

2 回答 2

2

The Standard states that the result of operator new should be suitably aligned for all types. This, however, does not include extended-alignment types like SSE types.

于 2013-07-11T18:23:14.800 回答
-2

If you use a union of A and B in the sizeof expression, only purists will complain. Like this:

union AllocObject {
    A a;
    B b;
};

main() {
    char* p = new char[sizeof AllocObject];
    ...
}

However, if you are concerned about new performance, you should consider implementing the global allocation operator yourself like this:

void* operator new (size_t size) {
    void* result = malloc(size);
    if(!result) throw(bad_alloc());    //Just for standard conformance, unnecessary on Linux...
    return result;
}

void operator delete (void *pointer) {
    free(pointer);
}

Of course, you can probably do better, but even the code above is 100 CPU-cycles faster than the builtin version on my machine...

Note that it is enough to have this in a C++ file that gets linked into the program, it is automatically called whenever your program uses the new operator.

于 2013-07-11T18:02:03.093 回答