1

I created a simple project just to test how deleting variable works but i encountered a strange thing... I created three int variables (1 stack based and 2 heap based) and when i deleted the heap variables using delete i still could access them. I can print them or change their value but how? Isn't delete supposed to permanently delete the variable from memory and also another question.... Why stack based variables can't be deleted using free() or delete?

Here is the (C++) script -

#include<iostream>
using namespace std;

void Stuff()
{
   int* heap_int = (int*)malloc(4); //Heap based variable
   *heap_int = 500;

   int  stack_int = 5; //Stack based variable

   int* calloc_int = (int*)calloc(1,2); //Heap based variable
   *calloc_int = 600;
  
  std::cout << "Value (HeapInt) : " << *heap_int << "\n"; //Prints 500
  std::cout << "Value (CallocInt) : " << *calloc_int << "\n"; //Prints 600
  std::cout << "Value (StackInt) : " << stack_int << "\n"; //Prints 5

  delete heap_int;
  delete calloc_int;
  //delete stack_int; (will not work)

  std::cout << "\nValue after delete (HeapInt) : " << *heap_int << "\n"; //Still prints 500
  std::cout << "Value after delete (CallocInt) : " << *calloc_int << "\n"; //Still Prints 600
  std::cout << "Value after delete (StackInt) : " << stack_int << std::endl; //Prints 5
 
  *heap_int = 82;
}

int main()
{
  Stuff();
}

I heard in online tutorials that heap based variables only get freed if we used delete or free() (unlike stack variables who get freed automatically when their scope ends) then why can't i access an heap based variable out of scope like this...?

#include<iostream>

void Function()
{
  int* variable = new int;
  *variable = 6;
}

int main()
{
   *variable = 9; //Error says "Use of Undeclared identifier variable"
}
trincot
  • 317,000
  • 35
  • 244
  • 286
CsharpUser
  • 31
  • 4
  • 1
    When you call `delete` or `free`, it doesn't mean the memory location disappears into thin air. That location is still there, it's just that it is undefined behavior to access it. – PaulMcKenzie Dec 29 '21 at 07:17
  • 1
    `malloc` is no C++. `malloc` goes with `free`, where `delete` goes with `new`, constructors, destructors and other stuff. – Sandburg Dec 29 '21 at 07:17
  • 1
    @Sandburg Well technically malloc is still there, but you can't create objects with it. Note that the C++ core guidelines recommend to not use new/delete, but use std::make_unique to avoid memory leaks and model clear ownership of pointers. (https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines and lookup things related to new/delete/pointers) – Pepijn Kramer Dec 29 '21 at 07:21
  • In C++ scopes are very well defined, any variable declared within a scope will not be accessible outside that scope. So that at least is how it should be in C++. Note : don't use "using namespace std" – Pepijn Kramer Dec 29 '21 at 07:25
  • Ah! Sorry.... I forgot to remove using namespace std btw thanks to all who answered – CsharpUser Dec 29 '21 at 08:44

1 Answers1

4

Reading the contents of a free'd or deleted memory address is called undefined behavior.

  delete heap_int;

  std::cout << "\nValue after delete (HeapInt) : " << *heap_int << "\n"; //Still prints 500

You might still be able to see the previous value at a deleted address, but it's definitely not guaranteed. As soon as the next malloc/new happens (or technically at any time), the memory manager might re-use that address for another object and overwrite what's there.

And this:

*heap_int = 82;

Similarly, writing to a deleted address is even worse undefined behavior - chances are high you have corrupted your program's behavior in strange ways, or at best, a fast crash.

why can't i access an heap based variable out of scope like this...?

Because you can't access any variable that's not in your scope or the parent scope. In your case, code in main can only access variables in that function or variables declared at global scope. That's the whole point of scope!

selbie
  • 100,020
  • 15
  • 103
  • 173