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.
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.
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.
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.
"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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With