For example .
When a function, that has a local integer variable x, ends, what does C++ do to the value stored at memory location corresponding to x?
Does it insert a random value?
What's probably happening - is nothing. Deleting something takes resources, so instead it just adjusts the pointer of the stack that is pointing to this memory. This will lead to overwriting it next time this memory is used.
You can see a similar thing while using a variable without initializing it.
int i;
i
will have "garbage" data in it, this "garbage" is from a time where this specific location in memory was in use. Could be an old photo, a text file or w/e.
This very much depends on the implementation.
In most cases nothing is done. You deallocate (which changes the stack pointer). You don't modify the memory in this case.
In some very obscure cases you may find different things done. In one example, the RTOS RTEMS can be set up to write to the memory in dealocation. It might write something specific like 0xCDCDCDCD
or 0xDEADBEEF
. This can be helpful when debugging memory issues in these RTOS systems because it is easy to identify when you are using bad memory. But this is very rare.
In theory this is not specified, but in practice no allocation is taking place for individual basic-type objects like int, double, T*, etc. In some cases, the stack pointer is not modified and the compiler simply reuses the space for other variables:
for (int i=0 ; i < 10 ; i++)
foo(i);
for (int j=0 ; j < 10 ; j++)
foo(j);
Most likely, the compiler will reuse the space of i
for allocating j
. This is easily verified on godbolt.org with gcc:
.L2:
mov edi, ebx
add ebx, 1
call foo(int)
cmp ebx, 10
jne .L2
xor ebx, ebx
.L3:
mov edi, ebx
add ebx, 1
call foo(int)
cmp ebx, 10
jne .L3
Not only the loops are identical, they don't even use the stack. Instead of the stack, both i
and j
variables are allocated on the `ebx. In this example, allocation and deallocation are completely transparent and are a simple use or no-use of registers.
int foo(int);
void bar(int*);
void bar()
{
{
int a[10];
for (int i=0 ; i < 10 ; i++)
a[i] = foo(i);
bar(a);
}
{
int b[10];
for (int j=0 ; j < 10 ; j++)
b[j] = foo(j);
bar(b);
}
}
Also, consulting second godbolt.org example produces:
xor ebx, ebx ; <--- this is simply part of the next block
sub rsp, 48; <--- allocating the stack space
.L2:
mov edi, ebx
call foo(int)
mov DWORD PTR [rsp+rbx*4], eax
add rbx, 1
cmp rbx, 10
jne .L2
mov rdi, rsp
xor ebx, ebx ; <--- this is simply part of the next block
call bar(int*)
.L3:
mov edi, ebx
call foo(int)
mov DWORD PTR [rsp+rbx*4], eax
add rbx, 1
cmp rbx, 10
jne .L3
mov rdi, rsp
call bar(int*)
add rsp, 48 ; <-- deallocating the stack space
Here also, the code is identical for the two cases. There is no deallocation or allocation of the variables on the stack. The line:
a[i] = foo(i);
is translated into
mov DWORD PTR [rsp+rbx*4], eax
which simply writes data relative to the stack pointer (rsp
). It basically finds the contents of a
according to its position relative to the stack pointer. The stack pointer is not updated between the two blocks of code, it is only passed to bar()
by copying the stack pointer to rdi
:
mov rdi, rsp
call bar(int*)
Unlike simple integer values, types with destructors are more complicated, but I will not go deeper on that because it was not asked in the question.
If you are creating an object and allocating a pointer to it
Animal* animal =new Animal() ;
It will allocate a memory region in the memory.It is like you are building a house and giving address to someone.
delete animal;
Will go to that memory region and destroy it.Like you trace the house with the address and destroying it. Then the value it holds will be garbage. As a good practice you have to make the address of the house nullptr
.
animal = nullptr;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With