Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ delete - It deletes my objects but I can still access the data?

I have written a simple, working tetris game with each block as an instance of a class singleblock.

class SingleBlock {     public:     SingleBlock(int, int);     ~SingleBlock();      int x;     int y;     SingleBlock *next; };  class MultiBlock {     public:     MultiBlock(int, int);      SingleBlock *c, *d, *e, *f; };  SingleBlock::SingleBlock(int a, int b) {     x = a;     y = b; }  SingleBlock::~SingleBlock() {     x = 222; }  MultiBlock::MultiBlock(int a, int b) {     c = new SingleBlock (a,b);     d = c->next = new SingleBlock (a+10,b);     e = d->next = new SingleBlock (a+20,b);     f = e->next = new SingleBlock (a+30,b); } 

I have a function that scans for a complete line, and runs through the linked list of blocks deleting the relevant ones and reassigning the ->next pointers.

SingleBlock *deleteBlock; SingleBlock *tempBlock;  tempBlock = deleteBlock->next; delete deleteBlock; 

The game works, blocks are deleted correctly and everything functions as it is supposed to. However on inspection I can still access random bits of deleted data.

If I printf each of the deleted singleblocks "x" values AFTER their deletion, some of them return random garbage (confirming the deletion) and some of them return 222, telling me even though the destructor was called the data wasn't actually deleted from the heap. Many identical trials show it is always the same specific blocks that are not deleted properly.

The results:

Existing Blocks: Block: 00E927A8 Block: 00E94290 Block: 00E942B0 Block: 00E942D0 Block: 00E942F0 Block: 00E94500 Block: 00E94520 Block: 00E94540 Block: 00E94560 Block: 00E945B0 Block: 00E945D0 Block: 00E945F0 Block: 00E94610 Block: 00E94660 Block: 00E94680 Block: 00E946A0  Deleting Blocks: Deleting ... 00E942B0, X = 15288000 Deleting ... 00E942D0, X = 15286960 Deleting ... 00E94520, X = 15286992 Deleting ... 00E94540, X = 15270296 Deleting ... 00E94560, X = 222 Deleting ... 00E945D0, X = 15270296 Deleting ... 00E945F0, X = 222 Deleting ... 00E94610, X = 222 Deleting ... 00E94660, X = 15270296 Deleting ... 00E94680, X = 222 

Is being able to access data from beyond the grave expected?

Sorry if this is a bit long winded.

like image 352
Ash Avatar asked Dec 18 '09 20:12

Ash


People also ask

What happens if you forget to delete an object that you obtained from the free store what happens if you delete it twice?

Typically, the free store is a carefully managed system of free and allocated blocks, and new and delete do bookkeeping to keep everything in a consistent state. If you delete again, the system is likely to do the same bookkeeping on invalid data, and suddenly the free store is in an inconsistent state.

What does delete actually do?

When delete is used to deallocate memory for a C++ class object, the object's destructor is called before the object's memory is deallocated (if the object has a destructor). If the operand to the delete operator is a modifiable l-value, its value is undefined after the object is deleted.

Can Free be used instead of delete?

In C++, the delete operator should only be used either for the pointers pointing to the memory allocated using new operator or for a NULL pointer, and free() should only be used either for the pointers pointing to the memory allocated using malloc() or for a NULL pointer. It is an operator. It is a library function.

Does C++ automatically delete objects?

"An object constructed by explicit or implicit use of a constructor is automatic and will be destroyed at the first opportunity (see §10.4. 10)." So if i define a new object of any class using a new function.


2 Answers

Is being able to access data from beyond the grave expected?

This is technically known as Undefined Behavior. Don't be surprised if it offers you a can of beer either.

like image 136
dirkgently Avatar answered Nov 01 '22 15:11

dirkgently


Is being able to access data from beyond the grave expected?

In most cases, yes. Calling delete doesn't zero the memory.

Note that the behavior is not defined. Using certain compilers, the memory may be zeroed. When you call delete, what happens is that the memory is marked as available, so the next time someone does new, the memory may be used.

If you think about it, it's logical - when you tell the compiler that you are no longer interested in the memory (using delete), why should the computer spend time on zeroing it.

like image 30
Martin Avatar answered Nov 01 '22 16:11

Martin