0

Could there be any reason why:

new X[n];

would consume more memory as compared to:

X* x = reinterpret_cast<X*>(malloc(n * sizeof(X))
for(X* p = x; p != x + n; ++p)
    new (p) X();

for multiple copies of multiple n's?

I am seeing evidence of this.

Tom
  • 6,601
  • 12
  • 40
  • 48

1 Answers1

5

Of course: Array-new is allowed to allocate more memory than just the space for the objects, and usually will do so. When you say delete [] x;, how would the implementation know how many destructors to call?

See 5.3.4/10:

A new-expression passes the amount of space requested to the allocation function as the first argument of type std::size_t. That argument shall be no less than the size of the object being created; it may be greater than the size of the object being created only if the object is an array.

The Itanium ABI is specific about the use of array cookies:

|<-- offset -->|
+--------------+----------+----------+---------+---------+
|(padding)  N  |   a[0]   |   a[1]   |   ...   |  a[N-1] |
+--------------+----------+----------+---------+---------+
^              ^
|              +---- T * a = new T[N]
|
+----  return value of `operator new(sizeof(T) * N + offset)`
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 2
    Won't any implementation of `malloc` store the same information? – David Heffernan May 17 '13 at 17:56
  • @DavidHeffernan That's what I was thinking about but I didn't dare to question KerrekSB's knowledge... –  May 17 '13 at 17:56
  • @DavidHeffernan: That's different. Of course somewhere internally someone will know how much memory is allocated for a given pointer. But that's unrelated. The memory allocator doesn't know about objects. – Kerrek SB May 17 '13 at 17:57
  • @KerrekSB Then what's the extra information needed? `n` objects -> `n` destructors, isn't it that simple? (So I suspect it isn't...) –  May 17 '13 at 17:57
  • @H2CO3: And given `x`, how do you know the value of `n`? – Kerrek SB May 17 '13 at 17:58
  • I guess that's because the actual block of memory might have some wasted space. And so you cannot calculate n by dividing the total block size by the element size. – David Heffernan May 17 '13 at 17:58
  • For a fun and insane related question, [see here](http://stackoverflow.com/q/8720425/596781). (A DR for this is in the pipeline.) – Kerrek SB May 17 '13 at 17:58
  • @KerrekSB 1. In the case of `malloc()`: given `p`, how do you know the size of the allocated memory? 2. Thanks for the link, reading. –  May 17 '13 at 18:01
  • @H2CO3: That's not our problem, that's the business of the memory allocator. Don't confuse memory and objects! – Kerrek SB May 17 '13 at 18:02
  • @KerrekSB I think I start to get this. Here, is the number of destructors to be called something that is to be visible externally? –  May 17 '13 at 18:05
  • @H2CO3: Not "externally" as such, but `delete [] x;` has to work. There's no other direct way for a user to inspect the size of the array, though (and if you check the Itanium ABI, in some cases there isn't even a cookie at all). – Kerrek SB May 17 '13 at 18:05