访问未分配的内存C++

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次迭代,并且可能不会产生两次.


tux*_*ux3 9

访问未分配的内存不能保证会抛出异常.

它实际上不能保证做任何事情,因为这是未定义的行为.什么事情都可能发生.小心鼻子恶魔.

它打印55因为你刚存储54,取回它然后打印54 + 1.它根本不能保证打印55,尽管这通常会在实践中发生.这次它奏效了.

  • ......当然,你踩过的记忆可能很重要,后来才能表现出来. (2认同)