C++ – What is the point of the delete keyword? [duplicate] - c++

This question already has answers here:
Why use new and delete at all?
(8 answers)
Use of new and delete in C++
(5 answers)
C++ is it necessary to delete dynamically allocated objects at the end of the main scope?
(7 answers)
Closed 3 years ago.
I am currently learning about dynamically allocated memory and have written a short program for practise.
Here is the main function:
int main() {
// Local variables are stored in the stack.
// The heap is a pool of unused memory that can be used when the program dynamically allocates memory.
// The `new` operator allocates memory within the heap and returns the address of that variable:
int *p = new int;
*p = 5;
cout << "A variable has just been allocated in the heap" << endl;
cout << "Its memory address is: " << p << endl;
cout << "Its value is: " << *p << endl;
// For local variables on the stack, memory management is performed automatically.
// But on the heap, it must be done manually.
// Memory must be freed when no longer needed:
delete p; // This frees up the memory pointed to by p.
// The `delete` keyword frees up the memory allocated for the variable, but does not delete the pointer p, because p is stored on the stack.
// p is now a dangling pointer, it points to a non-existent memory location.
// To test that it worked:
cout << "The memory previously pointed to has now been deleted." << endl;
cout << "Its memory address is: " << p << endl;
cout << "Its value is: " << *p << endl;
}
So far it makes sense, except for line delete p. At that point, the memory is supposed to be 'freed up'. I read the following page for information:
Delete in c++ program is not freeing up memory
The answer said:
Calling delete whatever marks that memory as deallocated and free for future use.
However, when I run the program, the two sets of cout statements output the same thing, which to me suggests that the memory has not been freed up, as p still points to the same location, which has the same value.
After some tinkering, I found that I can reallocate p whether or not I ran delete p and I could change the memory address and its value in either case.
So what exactly does delete p do, I don't notice it making any difference to the program?

Related

Memory isn't freed when scope is left in C++

I'm fairly new to C++ so please forgive me for my ignorance. I'm under the impression that anything between { and } is called a scope, and that you can create a separate scope inside a function, or anything else, just by adding more brackets. For example:
int foo(){
std::cout << "I'm inside the scope of foo" << std::endl;
{
std::cout << "I'm inside a scope that's inside the scope of foo" << std::endl;
}
}
I was learning about this in relation to pointers and memory leaks. My understanding is when you leave a scope all variables should be freed from memory unless the memory was manually allocated with new or malloc. In my testing, however, this does not seem to be the case. I've written the following script to test this:
#include <iostream>
void test(){
{
int regdata = 240;
int* pointerInt = new int(1);
*pointerInt = 15;
std::cout << "RegData Addr: " << &regdata << std::endl;
std::cout << "Value: " << regdata << std::endl;
std::cout << "Pointer Addr: " << &pointerInt << std::endl;
std::cout << "Pointer: " << pointerInt << std::endl;
std::cout << "Value: " << *pointerInt << std::endl;
std::cout << std::endl;
std::cout << "Press any key then enter to leave the scope.";
char temp;
std::cin >> temp;
//delete pointerInt;
}
std::cout << "The scope has been left." << std::endl;
std::cout << "Press any key then enter to leave the function.";
char temp;
std::cin >> temp;
}
int main(){
test();
std::cout << "The function has been left." << std::endl;
std::cout << "Press any key then enter to leave the program.";
char temp;
std::cin >> temp;
}
I start this program on my Windows 10 computer and have been monitoring the memory usage using the program Cheat Engine. Now, depending on whether or not I have delete commented out it will delete the bytes that hold 15 and replace them with random bytes when I leave the scope as it should. However, the memory holding the 240 is not freed until after I leave the scope of test (at which point the 240 is replaced with 1). And regardless of if the delete is commented out, the actual pointer itself is never deleted out of memory.
Is my compiler or my machine not compiling/running my code correctly? Or am I misunderstanding memory management between scopes? If it's the latter, please correct me so I can properly understand what is supposed to happen. Also let me know if something doesn't make sense!
Memory is not "freed" when you leave a scope. The lifetime of all variables with automatic storage duration that were declared within that scope end. What happens when the lifetime of a variable ends? For simple values like an int or a pointer: likely absolutely nothing. The lifetime of the variable has ended, so attempting to use it results in undefined behavior, but usually nothing will immediately happen to the value. The compiler knows that the storage in which the variable resided is now available to be re-used, but until it actually re-uses it the old value will likely continue to exist. A compiler could immediately zero out the memory of variables whose lifetime has ended, and for a debug build maybe it will, but doing so would take time so most compilers won't bother.
regdata is stored on the stack so the memory it uses will never normally be "freed" until the end of the thread that the code is running in.
What does happen is that the stack memory is now available again to be used for something else. Your calls to std::cout and std::cin will both need to use a certain amount of stack memory, if they use enough memory then they'll overwrite all of the values in your inner scope (depending on the implementation of your compiler, there's no guarantee that it'll reuse the inner scopes stack memory later in the function, it might decide it's faster to use more stack memory instead).
This is why regdata is always being overwritten with 1, it's a coincidence of later stack usage rather than a deliberate action by the compiler. Some compilers might deliberately overwrite stack memory after its released to help with debugging but in a normal release build that would be an unnecessary waste of time.

How to expand previously initialized memory size?

int main()
{
int *memory = new int[5];
cout << "Memory starts at: " << &memory[0]; // 0x56225460beb0
memory = new int[10];
cout << "\nMemory starts at: "<< &memory[0]; // 0x56225460c2e0
// different
cout << '\n';
return 0;
}
Is there a way to expand the previously initialized memory in C++, when initialized with new. Code above ends up creating a new memory location for memory. Does it also mean that previously allocated memory ends up taking space in my memory, because I didn't delete it
You can use std::vector, which for the most part over allocates, so expands without reallocating up to some extent.
You could also use malloc and realloc, which does something similar to vector, but I wouldn't recommend it since you have to manually call operator new and destructors.
You could also design your own allocator which does whatever you wish, but it's a bit more work, so I'd just stick with vector.
You can use realloc that is available from C language.
memory = (int *) realloc(memory, 10);
It would reallocate from the same address.

C++ pointer array is still accessible after delete[] is called [duplicate]

This question already has answers here:
c++ delete pointer issue, can still access data [closed]
(6 answers)
C++ delete - It deletes my objects but I can still access the data?
(13 answers)
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 6 years ago.
In the following code, delete[] is called once to free up the memory allocated by new. However, the array elements is still accessible after delete[] is called. I called delete[] twice to confirm that I am getting a double free or corruption error, which I am getting, which means the memory is freed. If the memory is freed, how am I able to access the array elements? Could this be a security issue which might be exploited, if I am reading something like a password into the heap?
int *foo;
foo = new int[100];
for (int i = 0; i < 100; ++i) {
foo[i] = i+1;
}
cout << foo[90] << endl;
delete[] foo;
cout << foo[90] << endl;
gives the following output
91
91
and
int *foo;
foo = new int[100];
for (int i = 0; i < 100; ++i) {
foo[i] = i+1;
}
cout << foo[90] << endl;
delete[] foo;
delete[] foo;
cout << foo[90] << endl;
gives
*** Error in./a.out': double free or corruption (top): 0x000000000168d010 ***`
The memory is free, which means it isn't attributed anymore, but the compiler's not going to take the extra effort to wipe it back to 0 everytime something's deleted.
It's also not going to take the effort to check that the memory is properly allocated before you access it - it'd reduce performance, and it assumes you don't do so. (Although tools like valgrind or debuggers can detect those wrong calls)
So it just changes the range of the memory as 'unassigned' internally, which means another call to new can use that same memory range. Then whatever data in that memory would be overwritten, and foo[90] won't return the same thing anymore.

memory content not erased after deleting my pointer (on a simple example) [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
Here is a simple of example of a question I have:
I create a pointer of integer (value 5), I print the pointer (hence the address) of the memory case it points to, as well as its content (5).
Then I delete that pointer, which is supposed to delete the content in the memory case that has the address of the pointer.
But then when I print a and its content, as expected the address still exists. Nevertheless the content remains the same (5) as if a was not deleted...
could you explain me? :-)
#include <iostream>
int main()
{
int * a = new int(5);
std::cout<< a << std::endl;
std::cout<< "--------" << std::endl;
delete a;
std::cout<< a << std::endl;
std::cout<< *a << std::endl;
// end of my main
return 0;
}
result:
0x7fff28403a90
--------
0x7fff28403a90
5
It may or may not print the same value after delete operation. So simply what you are observing is an undefined behavior.

Pointers pointing to variables(located on the stack) - C++ [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 8 years ago.
I guess this is a very basic question, but even after looking around on the internet for a while I can't seem to find a proper answer to this question.
I will refer to this tutorial on stack/heap:http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html
Let's say I write the following code:
void testVoid() {
int testVariable = 5;
}
If I'm not wrong, this function should create a variable located on the stack. As the functions exits, the allocated memory on the stack is deleted - so my variable should also have been deleted by then.
I have learned that pointers in c++ point to the memory location of a variable.
So if the variable pointed to by a pointer is located on the stack, and the stack then is cleared, I would expect not to be able to access original value through the pointer anymore, since the memory location pointed to is is cleared. However, I tested this:
int* pointer;
void testVoid() {
int num = 3;
pointer = &num; // Here I get the memory location of my num-variable
cout << pointer << " : " << *pointer << endl; // I would get the same result if i printed &num
}
int main(int args, char** argv) {
pointer = new int;
testVoid();
cout << pointer << " : " << *pointer << endl; // I can still access the memory of my num-variable
while (true) {}
return 0;
}
After exiting the testVoid()-function, where the variable is created, I can still get the value of the variable using my pointer. So obviously I have misunderstood something regarding how pointers work in c++. Printing &pointer and &num gives me the same memory location, even after testVoid() has finished. What is the reason for this? If the memory pointed to by the pointer were moved to the heap, shouldn't cout<<&num and cout<
And here's the output:
0024F904 : 3
0024F904 : 3
Just because the value goes out of scope does not mean the memory for the value has been overwritten. You just can't rely on it being stable at that point.