Clo*_*ock 3 c++ memory arrays pointers
我有这段代码:
try
{
int* myTestArray = new int[2];
myTestArray[4] = 54;
cout << "Should throw ex " << myTestArray[4] + 1 << endl;
}
catch (exception& exception)
{
cout << "Exception content: " << exception.what() << endl;
}
Run Code Online (Sandbox Code Playgroud)
对我来说真正的好处是,为什么没有抛出异常,因为它被访问了一个未分配的索引......以及为什么要打印55?是C++自动增加了数组的大小吗?
Cha*_*tin 10
这里有一个未说明的,不正确的假设.这个假设是C++实际上对你用内存做了什么感到很遗憾.C++与它的C祖先一样,具有完全未经检查的内存模型.你在这里经常被称为缓冲区溢出,并且是无数错误的来源,包括一些可怕的安全漏洞.
这是你的代码真正说的:
myTestArray是内存中一个位置的名称,大小足以容纳一个地址int.
int已经在堆上为它分配了两个内存.[而且那个地址被放到了这个位置myTestArray.没关系,但这可能会让它更清晰.](可能还有16个字节的开销,但我们现在不关心它.)
然后,您将该值54保存int在包含在其中的地址4 s 的内存位置myTestArray.
查看该位置,添加1并打印结果.
你证明C(++)确实不关心.
现在,在大多数情况下,底层内存管理和运行时系统都不会让你逃脱它; 你会违反它的假设并得到分段错误或类似的东西.但是在这种情况下,你还没有达到边界,很可能是因为你正在调整malloc正在使用的数据结构来管理堆.你正在逃避它,因为程序其余部分的堆没有发生任何事情.但是为了一个真正的美好时光,编写一个执行此代码的小循环,释放myTestArray并重新分配它.在程序爆炸之前我不会超过10次迭代,并且可能不会产生两次.
访问未分配的内存不能保证会抛出异常.
它实际上不能保证做任何事情,因为这是未定义的行为.什么事情都可能发生.小心鼻子恶魔.
它打印55因为你刚存储54,取回它然后打印54 + 1.它根本不能保证打印55,尽管这通常会在实践中发生.这次它奏效了.