2

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;
}
skydoor
  • 25,218
  • 52
  • 147
  • 201
  • 3
    This is kind of a duplicate of http://stackoverflow.com/questions/2498183/which-to-use-operator-new-or-operator-new-to-allocate-a-block-of-raw-me, but that question didn't actually generate any answers, just a lot of variants of "global operator new is a stupid feature which shouldn't be in C++ in the first place, and anyone who calls it smells of pants". This one, on the other hand, does have some answers, basically "it makes no difference, just use the right version of `operator delete`": http://stackoverflow.com/questions/2499895/whats-the-purpose-of-having-a-separate-operator-new – Steve Jessop Mar 26 '10 at 02:50
  • Had you remembered to `delete[]` your memory, you would have seen the only difference it makes. `:)` – sbi Mar 26 '10 at 06:58

4 Answers4

2

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
  • 277,958
  • 43
  • 419
  • 720
2

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
  • 134,909
  • 25
  • 265
  • 421
1

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
  • 10,791
  • 3
  • 29
  • 38
0

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
  • 476,176
  • 80
  • 629
  • 1,111