3

I need to construct an array of objects from a previously allocated block of memory. However, I cannot understand in what way ::operator new[]() is different from ::operator new() from the user point of view when allocating that block, since both require the size of the block. In the following example, using either one seems to have the same effect. Am I missing something?

class J {
};

int main() {
    const int size = 5;

    {
        J* a = static_cast<J*> (::operator new[](sizeof (J) * size));
        for (int i = 0; i < size; i++)
            new (&a[i]) J();
        for (int i = 0; i < size; i++)
            a[i].~J();
        ::operator delete[] (a);
    }

    {
        J* a = static_cast<J*> (::operator new(sizeof (J) * size));
        for (int i = 0; i < size; i++)
            new (&a[i]) J();
        for (int i = 0; i < size; i++)
            a[i].~J();
        ::operator delete (a);
    }
}
littleadv
  • 20,100
  • 2
  • 36
  • 50
Martin
  • 9,089
  • 11
  • 52
  • 87
  • possible duplicate of [What's the purpose of having a separate "operator new\[\]"?](http://stackoverflow.com/questions/2499895/whats-the-purpose-of-having-a-separate-operator-new) – Cheers and hth. - Alf Oct 18 '11 at 23:11
  • I don't think its the same. There the OP knew what the difference was and was asking why. Here the OP asks what the difference is. To someone who's fluent in C++ its easy to be confused, but it's definitely not the same question. – littleadv Oct 18 '11 at 23:14
  • @littleadv: as I see it (still, after considering your comment), it's definitely exactly the same question. – Cheers and hth. - Alf Oct 18 '11 at 23:40

2 Answers2

3

You're misusing the new.

The point of using new [] is that it calls the constructor for each and every element of the array being allocated. delete[] does the same for the destructors.

You're using placement new and manually calling the constructors and destructors, missing the whole point.

user541686
  • 205,094
  • 128
  • 528
  • 886
littleadv
  • 20,100
  • 2
  • 36
  • 50
  • Can you explain more, since I don't understand you. I want to not use new and delete[] deliberately. In case ::operator new has to be called separately from the construction of an array of objects, I don't see any difference between the two approaches. – Martin Oct 18 '11 at 23:11
  • It looked to me like the OP knew that. However, the question seems to be exact duplicate of earlier question. So I voted to close. – Cheers and hth. - Alf Oct 18 '11 at 23:12
  • @Martin, if you're using `new` as a substitute to `malloc` - there's no difference. That's not how `new` should generally be used (although its allowed in C++). – littleadv Oct 18 '11 at 23:12
  • I think I have confused you by also adding delete[] and delete() to the example, while my question is rather focused on the separation of the allocation from the construction of the array of objects. Suppose you are handling a pool of objects where you allocate the memory once for all , but construct and destruct often. If I have understood well, then there's no difference from the user point of view. Just out to my curiosity, what can be the difference about the implementations then? – Martin Oct 18 '11 at 23:29
  • @Martin - the point of `new` is to construct on allocation. If you have dynamic arrays - use `std::vector` with (or without) custom allocator which will eventually be reduced to `new`. I'll repeat, as it seems that it wasn't clear, **if you're using `new` as replacement for `malloc` then there's no difference, but that's not how `new` should be used in C++**. – littleadv Oct 18 '11 at 23:51
3

They're both allocation functions and thus they're both mandated to return suitable storage for the requested size (here that's sizeof(J) * size). That's why they make no difference in your code.

Where they differ is that operator new is the allocation function that is looked up in a non-array new expression (e.g. new J), whereas operator new[] is the allocation function that is looked up in an array new expression (e.g. new J[1]). This allows customization if a program has a particular strategy to allocate memory for arrays that differ from the strategy for allocating memory for single objects. If no such customization is needed then operator new[] can just delegate to operator new (and this is in fact what is mandated for the allocation functions provided by the implementations, i.e. ::operator new and ::operator new[]). So that difference isn't relevant for your code.

Luc Danton
  • 34,649
  • 6
  • 70
  • 114
  • Might be worth mentioning that `new J[1];` will typically request more than `sizeof(J) * 1` bytes from the allocation function. – Kerrek SB Oct 18 '11 at 23:46
  • @KerrekSB I don't think new expressions (other than the usual placement new) are really the focus here. – Luc Danton Oct 18 '11 at 23:49