views:

197

answers:

4

For a class without default constructor, operator new and placement new can be used to declare an array of such class.

When I read the code in More Effective C++, I found the code as below(I modified some part).....

My question is, why [] after the operator new is needed?

I test it without it, it still works. Can any body explain that?

class A {
    public:
    int i;

    A(int i):i(i) {}
};

int main()
{
      void *rawMemory = operator new[] (10 * sizeof(A));   // Why [] needed here?
      A *p = static_cast<A*>(rawMemory);

      for(int i = 0 ; i < 10 ; i++ ) {

            new(&p[i])A(i); 

      }

      for(int i = 0 ; i < 10 ; i++ ) {

            cout<<p[i].i<<endl;

      }

      for(int i = 0 ; i < 10 ; i++ ) {

            p[i].~A();

      }

    return 0;
}
+1  A: 

It's not needed. The only difference between operator new and operator new[] is that the first is called by usage of keyword new and the other by keyword new[]. Both allocate raw memory.

Just make sure when you finally free the memory (your code here just leaks) that you call the delete or delete[] that matches new or new[].

Ben Voigt
+1  A: 

It isn't strictly needed in this case. They both will allocate the same amount of memory, but one will require delete and one will require delete[] at the end. Using new[] makes your intent somewhat more clear, which is why it is used here.

Dennis Zickefoose
A: 

It's not really needed -- it just gives you a chance to allocate memory for arrays separately from memory for single objects, if you choose to do so.

Jerry Coffin
+2  A: 

I'm surprised that Effective C++ would be advising you to use something as hackish as a void*.

new[] does a very specific thing: it allocates a dynamically sized array. An array allocated with it should be passed to delete[]. delete[] then reads a hidden number to find how many elements are in the array, and destroys the objects as you have done with p[i].~A();.

However, this usage is incompatible with that. The array is statically sized, and there's no way to get that hidden number or dynamic-size destruction without properly using new[] (no operator), in turn requiring a default constructor. A genuine weakness of C++.

If you called delete[] at the end of main as others have suggested, your code could crash. Instead you need to use operator delete[], which looks like a typo and is just an accident waiting to happen.

Use non-array operator new and operator delete and ample comments if you must use this trick. But I wouldn't consider this particularly effective C++.

Potatoswatter