Values still accessible after I call delete, c++ [

2020-08-01 06:09发布

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:

  1. I need to set up all the BankAccounts in each Employee with values
  2. 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);
}

2条回答
干净又极端
2楼-- · 2020-08-01 06:29

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

  • Execute the destructor

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.

查看更多
Melony?
3楼-- · 2020-08-01 06:39

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!

查看更多
登录 后发表回答