Ash*_*Ash 30 c++ pointers c++-faq undefined-behavior
我写了一个简单的,工作的俄罗斯方块游戏,每个块作为类单块的一个实例.
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);
}
Run Code Online (Sandbox Code Playgroud)
我有一个扫描完整行的函数,并运行删除相关的块的链接列表并重新分配 - >下一个指针.
SingleBlock *deleteBlock;
SingleBlock *tempBlock;
tempBlock = deleteBlock->next;
delete deleteBlock;
Run Code Online (Sandbox Code Playgroud)
游戏工作,块被正确删除,一切都按照预期运行.但是在检查时我仍然可以访问已删除数据的随机位.
如果我删除它们后删除了每个删除的单个块"x"值,其中一些返回随机垃圾(确认删除),其中一些返回222,告诉我即使析构函数被调用,数据实际上并未从中删除堆.许多相同的试验表明它总是与未正确删除的相同特定块相同.
结果:
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
Run Code Online (Sandbox Code Playgroud)
是否能够访问超出预期的数据?
对不起,如果这有点长啰嗦.
dir*_*tly 78
是否能够访问超出预期的数据?
这在技术上称为未定义行为.如果能为您提供一罐啤酒,请不要感到惊讶.
Mar*_*tin 31
是否能够访问超出预期的数据?
在大多数情况下,是的.调用delete不会使内存归零.
请注意,未定义行为.使用某些编译器,可以将存储器归零.当您调用delete时,会发生内存被标记为可用,因此下次有人新建时,可能会使用内存.
如果您考虑一下,这是合乎逻辑的 - 当您告诉编译器您不再对内存感兴趣时(使用删除),为什么计算机会花时间将其归零.
删除不会删除任何内容 - 它只是将内存标记为"可以重复使用".在某些其他分配呼叫预留并填充该空间之前,它将具有旧数据.然而,依靠这是一个很大的禁忌,基本上如果你删除了忘记它的东西.
在库中经常遇到的这方面的一种做法是删除功能:
template< class T > void Delete( T*& pointer )
{
delete pointer;
pointer = NULL;
}
Run Code Online (Sandbox Code Playgroud)
这可以防止我们意外访问无效内存.
请注意,打电话是完全可以的delete NULL;
.
小智 6
堆内存就像一堆黑板。想象你是一位老师。当你在教你的课时,黑板是你的,你可以用它做任何你想做的事。您可以在上面随意涂鸦并覆盖内容。
当课程结束并且您将要离开房间时,没有规定要求您擦除黑板——您只需将黑板交给下一位老师,他通常能够看到您写下的内容。