0

I have a member function that I call, from there I get a pointer to a private member which is of class BankAccount, I am unsure what happens with the pointers when I deallocate them. I create a new pointer and heap memory address but then assign the pointer to something else. What does "delete" end up deleting?

I read that if you delete a pointer

Here is the code

void Employee::raise(){

    BankAccount* tempBank = new BankAccount(); //set pointer to new heap place

    double amt;

    tempBank = get_bank(); // set pointer to existing heap implicitly
    amt = tempBank->get_amount();
    amt = (amt + (amt/12));
    tempBank->set_amount(amt);


    delete tempBank; //does this delete new heap created or does it add a new block of
                     //memory to heap since it is trying to delete a pointer assigned 
                     //by memory address
    tempBank = NULL;
}

I realized I could just do the code below to avoid this situation, but now I am curious as to what happens in the above situation with the memory

BankAccount* tempBank = get_bank();

So what exactly happens when delete is called in my original situation?

trincot
  • 317,000
  • 35
  • 244
  • 286
user2076774
  • 405
  • 1
  • 8
  • 21

6 Answers6

1

When you use delete ptr; the object pointed to by ptr is destroyed and the corresponding memory is returned to the memory management system. The variable ptr and any copy thereof hold a bit pattern referring to now inaccessible memory (the system may still allow you to actually access this memory and it may even still contain the original data but that's undefined behavior and you shall not rely on it).

Put differently, the memory deallocation does not affect the pointer but it does affected the pointed to entity. In your case, the BankAccount, i.e., the result of *tempBank gets destroyed while the pointer tempBank remains unchanged by the delete operation. Obviously, setting tempBank to NULL does change this specific pointer but none of the other copies (if any), giving you false sense of security: I'd not set deleted pointers to NULL unless I keep them around for whatever reason...

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • I disagree: if you have to use raw pointers, setting them to NULL/nullptr is the only way to clearly mark them as 'not pointing to anything sensible', which in my experience helps a lot if you're encountering dereferencing problems. And you never know how somebody else might eventually modify your code (and reuse a pointer that you never intended to be reused) – mvd Dec 02 '15 at 09:17
  • 1
    @mvd: Note that `tempBank` goes out of scope immediately after being set to `NULL`. What is the point of that? – Dietmar Kühl Dec 02 '15 at 09:25
  • In this case you're right. But maybe some time later this function gets extended, possibly by somebody else who does not pay attention. Moreover: I find it a lot safer to have good default-habits. I don't want to think about whether the pointer might still be used somewhere else and only then reset it. In stressful phases I'm sure to forget one and that sure'll bite me when I can least afford it ;-) Anyway, I hope we all agree that owning raw pointers are an anti-pattern in contemporary C++. – mvd Dec 02 '15 at 10:41
  • @mvd: the key issue is actually code along the lines of `T* ptr2 = ptr1; ... delete ptr2; ptr2 = 0;` The fact that `ptr2` got set to null does not affect `ptr1`. That is, when you are juggling pointers you need to be aware which pointers are valid where. Setting some pointers to null gives a false sense of security. I do agree that owning raw-pointers are a bad idea in most cases (obviously, when implementing a resource manager they'll still emerge). – Dietmar Kühl Dec 02 '15 at 10:46
1

Pointers are essentially just the address of the first byte in memory that belongs to the data structure they point to. So in your case:

BankAccount* tempBank = new BankAccount(); // this creates a new object of type BankAccount
                                           // the pointer tempBank points to the first byte of that object in memory

tempBank = get_bank();  // now tempBank points to the first byte of whatever is returned from get_bank()
                        // that means that you no longer know the address of the object you created above (tempBank now points to something different)
                        // C++ has no garbage collection, so you just leaked that memory

delete tempBank; // you delete the object that was returned from get_bank
                 // so that memory is now marked as free and can be reused by whatever needs it

tempBank = NULL;  // this is good style, you should always do it, but it does nothing to any allocated memory

BTW: using plain new and delete and owning raw pointers is considered bad style in modern C++. YOu might want to consider using std::shared_ptr or std::unique_ptr (or their boost equivalents if you cannot use C++11 yet)

mvd
  • 246
  • 1
  • 7
  • Oops, got me. I was not accurate in my answer: although there are a lot of C++ developers who actually think all raw pointers are bad, IMHO **owning raw pointers** should be avoided. I edited the answer, thanx for the question. One of the main reasons is, that you have to delete them manually somewhere, and this is easily forgotten - which results in a memory leak. Or you call delete on the same pointer twice, which will crash your program. For further reading I recommend Scott Meyer's 'Effective Modern C++', chapter 4. – mvd Dec 03 '15 at 09:06
  • Personally I think that **non-owning** raw pointers are fine, and I'm happy that this opinion is shared by no other than Bjarne Stroustrup himself (https://www.youtube.com/watch?v=1OEu9C51K2A from roughly 24:00) – mvd Dec 03 '15 at 09:06
0

I found this information that may be useful to you:

ordinary delete Deallocates the memory block pointed by ptr (if not null), releasing the storage space previously allocated to it by a call to operator new and rendering that pointer location invalid.

You can find more information in the original url: http://www.cplusplus.com/reference/new/operator%20delete/

Ramón Esteve
  • 11
  • 1
  • 4
0
delete tempBank;

when delete is called on pointer , it releases memory pointed by that variable[tempBank].

There are two notions of delete in C++: One is the operator, declared as ::operator delete(void*), which basically only frees up the memory and isn't usually thought about by most programmers. The other is the delete expression, delete p;, where p is a T*. The expression invokes the destructor of the object pointed to by p (and then frees the memory), which is a crucial language feature of C++ that has no analogue in C.

anshul garg
  • 473
  • 3
  • 7
0

Well first of all, you are allocating from heap with your first exp which is

BankAccount* tempBank = new BankAccount();

and you lose the address of it with assigning another object address to tempBank pointer by

tempBank = get_bank();

so actually when you delete tempBank; you actually deleting the object that you allocated in the function get_bank(). Also because you have lost the address of object that you allocated with new BankAccount(), there is no more way to delete it, because you do not know the address of this object.

cavitsinadogru
  • 940
  • 2
  • 10
  • 17
0

In your question, Are you sure that get_bank() indeed returns pointer to object allocated on heap (and not address of just plain object on stack). You have not mentioned it clearly hence it's worth to confirm it again. Now, coming back to question, if get_bank() returned pointer to private member which let's say was not on heap - in that case doing doing tempBank will result in undefined behavior because you can only invoke delete on an object which was created using new. But if get_bank() returned pointer to object allocated on heap then it will free memory of that object and then accessing that object from any other member function could become a nightmare!

You can check below link for some more related information,

Calling delete on variable allocated on the stack

Community
  • 1
  • 1
Pravar Jawalekar
  • 605
  • 1
  • 6
  • 18