views:

176

answers:

4

Hi,

Is it true that a pointer assigned to the starting address of a dynamically allocated array does not have the information of the size of the array? So we have to use another variable to store its size for later processing the array through the pointer.

But when we free the dynamically allocated array, we don't specify the size, instead we just "free ptr" or "delete [] ptr". How could free or delete know the size of the array? Can we use the same scheme to avoid storing the size of the array in another variable?

Thanks!

+13  A: 

Yes, this is true.

delete knows the size of the memory chunk because new adds extra information to the chunk (usually before the area returned to the user), containing its size, along with other information. Note that this is all very much implementation specific and shouldn't be used by your code.

So to answer your last question: No - we can't use it - it's an implementation detail that's highly platform and compiler dependent.


For example, in the sample memory allocator demonstrated in K&R2, this is the "header" placed before each allocated chunk:

typedef long Align; /* for alignment to long boundary */

union header { /* block header */
  struct {
    union header *ptr; /* next block if on free list */
    unsigned size; /* size of this block */
  } s;

  Align x; /* force alignment of blocks */
};

typedef union header Header;

size is the size of the allocated block (that's then used by free, or delete).

Eli Bendersky
Note that the size of the allocated block from the point of view of the allocator implementation might be larger than the size requested by the user.
Nick Guerrera
Also, beyond the size of the raw underlying block, if a type T has a destructor, then the system must store `n` passed to `new T[n]` _somewhere_ so that it can call the destructor `n` times when `delete[]` is called. Of course, how and where it stores `n` remains just as implementation specific as the storage of the raw block size.
Nick Guerrera
+3  A: 

It is true that the array does not contain the size of the array, you have to store that information for later. When deleting an array through delete or free it is the pointer to the allocated memory you pass. The memory manager used (either by the system or your own custom from overriding new and delete) knows the memory area that is freed, and keeps track of it. Hope it makes sense.

TommyA
+2  A: 

Yes, it's true. This is part of why you should rarely try to deal with this directly, and use a standard container instead. About the only time it makes sense to deal with it is if you decide to implement a container yourself (in which case you'll normally track the size information in your container's implementation).

Jerry Coffin
+5  A: 

The funny thing is that historically it was delete [20] arr; just as it is arr = new int[20]. However practice proved that the information on size can be painlessly stored by the allocator, and since most people using it then stored it anyway, it was added to the standard.

What is more funny, and little known, is the fact that this "extended delete syntax" is in fact supported by a few C++ compilers (despite being incorrect even in face of the C++98 standard), although none require it.

int* arr = new int[20];
delete [20] arr;

The sad part about this all however is, that there's no standard-conforming way to retrieve that passed size for your own use :-/

Kornel Kisielewicz
It might be "supported" - it is not part of the C++ Standard.
anon
True, I expanded my answer a little. I wonder if there's any standards document av available produced that documents that "feature".
Kornel Kisielewicz