开发者

How does the delete in C++ know how many memory locations to delete

开发者 https://www.devze.com 2022-12-20 23:16 出处:网络
how does the delete operator work? Is it better then free()?. Also if u do ptr=new char[10], then delete using delete ptr, how does the pointer know how many 开发者_运维知识库locations to delete.There

how does the delete operator work? Is it better then free()?. Also if u do ptr=new char[10], then delete using delete ptr, how does the pointer know how many 开发者_运维知识库locations to delete.


There is only delete operator, free exist only as function. Under C++, you are encouraged to use new/delete over malloc()/free().


There is an internal "magic" in delete operator. When an array is created with new[], the size of array is stored in the metadata at the memory block. delete[] makes use of that information.

All this is of course compiler-, OS-, optimizer- and implementation-dependent.


if you do a non-array type:

T t = new T;
// ...
delete t;

It will know how much to delete because it knows how big a T is. If you do an array:

T t* = new T[10];
// ...
delete [] t;

It will lay down some extra info with the allocation to tell it how much to delete. Note, we use delete [] t with the extra [] in there to tell it it's an array. If you don't do that it will think it's just a T and only free that much memory.

Always use delete if you use new and free if you use malloc. new does 2 things first it allocates the memory, then it constructs the object. Similarly delete calls the destructor and then frees the memory. malloc\free only deal with the memory allocation and deallocation.


  1. In C++, a constructor is called using new, but not when using malloc. Similarly a destructor is called when using delete, but not when using free.

  2. If you have new-ed an array using MyClass* x = new MyClass[25], then you need to call delete[] x, so that they system knows that it's deleting (and destructing) a group of objects instead of a single one.


The implementation works out the number of elements to destroy (when using delete[]) for you. For example:

  • new char[10] could allocates a few extra bytes, put the number of elements at the beginning, then return the pointer to the first element after that. delete[] could then look behind the pointer at the stored count
  • store the equivalent of std::map<void*, size_t>, and new T[n] would create a key with the returned pointer, and a value with the count. delete[] would look up the pointer in this map
  • something completely different. It doesn't matter to you how it's done, just that it is done (and as other answers have pointed out, use delete[] with new[]!!)


It is not a question of better or worse. Both are operations with the same goal, allocating and releasing memory, but usually used within a different context of C vs. C++. Furthermore, there are some important differences between the two sets of operations:

  • new / delete are C++ keywords, and are not available in the C language
  • new / delete are type safe, whereas malloc() / free() are not. This means that pointers returned by malloc() and free() are void pointers that need to be cast to the correct type.
  • new / delete implicitly support array allocation and deletion using the new[] and delete[] syntax using meta-data supplied by the compiler, malloc() / free() do not support this syntax
  • applying new / delete to a class type T will call the constructor and destructor respectively of T, malloc() / free() do not call the constructor and destructor of T
  • malloc() will return NULL in case of memory exhaustion, new will throw an exception

Note that to prevent memory corruption, memory allocated using new should be freed using delete. The same holds for memory allocated using malloc(), which should be freed using free().


Specifically answering your question, the delete operator invokes the destructor, where free does not; hence the reason you don't want to mix malloc/free with new/delete.

When the compiler's library grabs memory from the heap, it grabs a little more than you ask for which includes space for it's house keeping, some meta data, and if required, padding.

Say you malloc 128 bytes, or new an array of eight 16 byte-sized objects. The compiler might actually grab 256 bytes, include a small heap management block at the start, record that it gave you 128 but grabbed 256, and return you an offset into that 256 block somewhere after it's header. You are guaranteed that from that pointer you have 128 bytes that you may use, but if you go beyond that, you could run into trouble.

The free and delete operators under the hood will take the pointer you were handed, back up a known offset, read it's header block, and know to release 256 bytes back to the heap.


Adding to @Vlad's answer if you allocate memory using new[] form of the operator like:

char *c = new char[10];

then you have to use the corresponding delete form:

delete[] c;

You have to explicitly tell the compiler to use the metadata during deallocation.

[EDIT]

Why you cannot use char c[]

Because the compiler needs to know the size it needs to set aside for variable c at compile time. However, using the new[] form tells it to defer allocation until runtime. Hence, the compiler error.

0

精彩评论

暂无评论...
验证码 换一张
取 消