This question already has answers here:
Closed last year.
I have to classes, one Employee
class and one BankAccount
class, the employee class has the BankAccount
class as a private variable pointer.
This is what I am trying to do:
- I need to set up all the
BankAccount
s in each Employee
with values
- then I delete all
BankAccounts
for every Employee
at the end of the function.
I use a member function setter in Employee
to set up the BankAccount
pointer. BankAccount
has one private variable and that is amount. Later I call delete on a pointer that should point to each BankAccount's
memory address. After I call print to see the values of the bank for each Employee
and it is still printing values for each BankAccount
If I call delete shouldn't the memory on heap be delete and when print is called not output anything for BankAccount
?
Here is the code:
vector<Employee*> employees;
//get employee full name & salary and return
employees.push_back(get_employee_info());
//setup their bank account
setup_bank(employees);
//make temp pointer to store bank memory address
BankAccount * tempBankPtr;
for (int i =0; i < employees.size(); i++) {
tempBankPtr =employees[i]->get_bank();
delete tempBankPtr // delete the heap object that pointer is pointing at
}
//print values
for (int i =0; i< employees.size(); i++) {
employees[i]->print();
}
code for print
void Employee:: print() const {
cout << "First name is: " << firstName << "\n";
cout << "Last name is: " << lastName << "\n";
BankAccount* bankholder = NULL;
bankholder = get_bank();
if(bankholder != NULL)
cout << "Account Balance is: " << get_bank()->get_amount() << "\n"; //prints values
}
getter for bank
BankAccount* Employee::get_bank() const{
return bank;
}
this is called in setup_bank
void Employee::set_bank(Employee* e, double amount){
bank = new BankAccount(amount);
}
If I call delete shouldn't the memory on heap be delete and when print is called not output anything for BankAccount?
No.
Deleting the object at that location in memory means it does not exist any more, so you're not allowed to access it.
It does not mean your program will magically print "nothingness" to protect you from this mistake.
Your program therefore has undefined behaviour; you must make sure you do not dereference an invalid pointer!
A very nice explanation of how free works.
When you call delete on the pointer and unlike as it has been suggested above you should only expect the following
The memory is not set to zero or any other magical value, since that is a very very expensive operation. When free
is going to be called and if furthermore this will cause a call to sbrk
is largely implementation dependent. The latter returns memory to the operating system.
For example AIX is well known to have a quite complex mechanism for memory management. What you should expect is that actually the block of memory will be marked as reallocatable , and new objects might overwrite your after the address pointed. Until this happens, you old staff are most probably still there.
Furthermore unlike stated before you can very well access it for as long as the data segment has not been reduced, and actually the object still exists , it is just that only you know about it.
That is why in this case you do not get SIGSEGV as you would expect. You probably get it later when you allocate something and the addressing a pointer in that memory area executes arbitrary code.
Accessing a delete pointer is undefined behavior and deleting it a second time is even more dangerous. To alleviate the situation there are many techniques , the most simple being encapsulation and deleting the pointer on the class destructor. You should set the pointer to nullptr.
Simplicity stops here, since you have to apply the rule of three (and a half ) . Thus it is better to work with shared or unique pointer provided by c++11 , and ignore these issues for now.