Confusion in syntax related to Deallocating Heap Arrays [duplicate] - c++

This question already has answers here:
delete vs delete[] operators in C++
(7 answers)
Closed 5 years ago.
When we deallocate the heap memory occupied by an array, I have a little confusion regarding the syntax
int *p = new int[5];
Now for deallocating, which one is correct from the following:
delete p;
OR
delete[ ] p;
The latter seems to be more correct. But it confuses me, I don't understand that how would it know that how much memory the array exists on. I mean, we are only giving it the starting address of the array(through p). So, beginning from the starting address how will the compiler know that till where does it have to deallocate, and when to stop the deallocation.

Your second syntax is correct, and the compiler knows the size of the array since it took note of it when you allocated the array.This is usually stored in a piece of memory just before the memory that you allocated for the array. That way when it's time to free the memory, the deallocator knows exactly how much memory to free, by checking this memory.

In the below statement you are creating memory dynamically for int array of 5 integer
int *p = new int[5];
Its looks like below
p = operator new [] (20); /** p points to first 20 bytes from starting address **/
To free or de-allocating p you should use
delete [] p;
It's looks like below
operator delete [] (p); /* It free frees memory of 20 bytes from where p is pointing */
Note : if you using only delete p then it won't free whole 20 bytes. delete p internally converts as operator delete (p);

Related

How delete[] works behind the scene in c++? [duplicate]

This question already has answers here:
How does delete[] "know" the size of the operand array?
(9 answers)
Closed 3 years ago.
when we allocate memory dynamically using new operator for a int data type. it makes sense to use delete operator.
For example
if a code would like bellow :
int *p=new int;
delete p;
Here it makes sense to use delete . Here we can think like this that the block, p points ,delete/de-allocate that memory block .
But for the bellow code :
int *p=new int[5];
delete[] p;
How does it make any sense to use delete[] here. I am asking this because p is not the name of the array. Here p is just a simple pointer which is pointing to the first element of the array memory block. Now how does delete[] works to delete the whole array.As here was not mentioned the size of the array. Then how does the statement delete[] p; delete the whole array.
It's up to the compiler to figure out how to do that. One fairly standard way to do this is to store the size of the array in a technical header that precedes the allocated memory block.

Questions on delete[] operator when pointer to an array is involved

The following code compiles but runs with mistake:
int main() {
int (*d)[2] = new int[3][2];
// do something
delete [] *d; // this is wrong
delete [] *(d+1); // this is also wrong
//delete [] d; // this works
return 0;
}
I do not know why "delete [] *d" does not work because *d seems to be a pointer to a chunk containing 2 integers and delete[] should destroy that chunk.
Furthermore, I am not sure whether "delete [] d" is enough to release all six elements since two-dimension array is involved here.
Thanks!
The memory you allocated is allocated as one continuous block (or chunk) of memory that stores an array obejct of int[3][2] type. It should be freed as one block
delete [] d;
That's all you need to do.
Freeing just some partial sub-block of a whole block is not supported by C++ dynamic memory management mechanisms.
Your delete [] *d is indeed wrong - the behavior is undefined. However, it has a good chance of "working" in practice since int (*)[2] pointer d and [decayed] int * pointer *d point to the same spot in memory, and the underlying types are trivial. If it "works", it should typically have the same effect as delete [] d;, i.e. free the entire 2D array.
int[3][2] is not a pointer of pointers but just a multi-dimensional array, allocated as a single pointer.
You cannot delete "lines" of it because there are no lines. Memory is contiguous.

error in releasing the static array in debug mode [duplicate]

This question already has answers here:
Must I delete a static array in C++?
(4 answers)
A bit confused on exact meaning of dynamic memory allocation for C++
(2 answers)
Closed 7 years ago.
Why it has error in releasing the static array in debug mode?
int main()
{
int ar[] = { 1,2,3,4,5,6,7,8,9 };
//other code
delete(ar);
// or free(ar);
return 0;
}
I used free or delete to release the array and it finished with error in debug mode.
Do i use the free or delete correctly?
How can i release the array?
ar[] is not allocated on the heap, but local/on the stack, so can't be (and shouldn't be) deleted.
The memory is released on function (or block {}) exit.
You can only use delete with new or free() with malloc()
the delete operator and 'free' function are to be used only on pointers that
own memory allocated on the heap. your array is allocated on the stack, and
the internal implementation will crash when it will not find any heap structure.
moreover, delete is only to be applied on memory allocated with new
and free only on memory allocated with malloc,calloc or realloc.
last thing is that when you use delete on an array, use delete [] for
this means that the removal will take place on an earlier offset on the stack,
when the record of the array itself is allocated, doing otherwise might end with a memory leak or worse

Using new for an already valid pointer

If I've already used new to allocate memory to int* p, but then if I want use new again, will the previously allocated memory remain valid?
int *p;
p= new int[5]; //is this going to remain valid after the following statement?
p= new int[10];
If yes, then am I required to delete[] it? I tried doing that but the compiler says that the pointer is valid, so I can't delete it. Is there any other way to get rid of the previously allocated memory?
The second use of new[] is, in itself, completely independent of the first. The second use of new[] does not in any way invalidate the first block of memory that you allocated.
When you allocate memory, you are asking the system to allocate memory, and tell you the address of the memory that it, the system, allocated. It is your responsibility to remember that address so that you can refer to it in the future. You need to be able to refer to the memory in order to access it and eventually deallocate it.
This is your code:
int *p;
p= new int[5];
p= new int[10];
The first assignment records the address of the first allocated block. The second assignment overwrites that value with the address of the second block.
So, the problem you have is that you no longer have a variable that contains the address of the first block of memory. Whilst that first block is still valid, you are unable to refer to it. In particular, since you can no longer refer to it, you cannot deallocate it and so it will be leaked.
If you wish to be able to deallocate both blocks of memory, then you have to be able to refer to both blocks. Which means that you must have two variables to hold the two distinct addresses.
int* p1 = new int[5];
int* p2 = new int[10];
Now you can refer to blocks blocks separately. When you are done, deallocate the memory:
delete[] p1;
delete[] p2;
On the other hand, if you want to delete the memory before allocating a new block, you can do that:
int* p = new int[5];
// use p
detete[] p;
int* p = new int[10];
// use p
delete[] p;
The prev remain somewhere on the heap. You can use valgrind to verify that. If you want to use the sane pointer again and again you might consider to create a function that delete the last allocation and allicate new space each time...
To add to what David Heffernan said, when you have this statement:
int *p;
p= new int[5];
don't think of p as being assigned to the memory that was allocated. The memory exists independently of p, but you're using p as a sort of post-it note to jot down where that memory is located. When you assign a new value to p, you're simply overwriting your note. You haven't done anything to the memory that was allocated-- you just don't know where it is anymore.
If the memory you previously allocated is not needed anymore, you have to use delete [] to free the memory. Otherwise, the memory is still out there, but you have no way to access it any more, thus a memory leak.
You will need to delete[] p; in order to avoid memory leak. The memory doesn't get released by itself. What's the exact information the compiler is giving in terms of "can't delete it"?

What does delete[] do if given a pointer to the middle of an array? [duplicate]

This question already has answers here:
Can I delete[] a pointer that points into an allocated array, but not to the start of it?
(7 answers)
Closed 9 years ago.
What would happen in the following code?
int *p1 = new int[100];
int *p2 = &p1[50];
delete [] p2;
I've heard that some implementations of new store the size of the array in the (-1)th array index, but then wouldn't things go horribly wrong in the above?
Things would definitely go wrong!
The delete [] operator is defined to only work on proper array pointers. And by proper I mean it must receive a pointer that was previously initialized to point to a location in memory where an array was created with the new operator.
You should also never mix and match new/delete and malloc/free. As a rule always delete memory that has been allocated with new, and free memory that has been allocated with malloc (and derivatives)