sil*_*eth 8 c++ linux windows memory-management
为什么这样做?
#include <iostream>
using namespace std;
int main() {
float* tab[3];
int i = 0;
while(i < 3) {
tab[i] = new float[3-i];
i++;
}
cout << tab[2][7] << endl;
tab[2][7] = 6.87;
cout << tab[2][7] << endl;
i = 0;
while(i < 3)
delete[] tab[i];
}
Run Code Online (Sandbox Code Playgroud)
虽然这个没有?
#include <iostream>
using namespace std;
int main() {
float* tab = new float[3];
cout << tab[7] << endl;
tab[7] = 6.87;
cout << tab[7] << endl;
delete[] tab;
}
Run Code Online (Sandbox Code Playgroud)
我在Win XP上使用MS VS 2008尝试了两个程序,两个程序都编译没有错误,第一个程序运行没有任何错误.第二个弹出一些错误窗口,但是我记不住它了,无法重现(目前无法访问Windows).
我也尝试使用g ++在Linux(带有预编译内核包版本2.6.35.23.25的Kubuntu 10.10)上进行编译和运行,没有任何错误.
为什么?不应该有任何弹出窗口,例如"错误访问未分配的内存"?
我知道它应该(并且,幸运的是)编译没有错误,但我认为它不应该没有它们运行...为什么第二个例子在Windows上而不是在Linux上发生错误?
使用未分配的内存会导致未定义的行为.即使在相同的系统和编译器上执行此操作,您也不会期望会发生什么,更不用说跨硬件和编译器的不同组合了.
程序可能会立即崩溃,它可能会工作一段时间然后再失败,它甚至可能看起来完美无缺.
但是,访问您不拥有的内存始终是一个编程错误.不要把正确操作的外观想象为"它有时会起作用",把它想象成"我真的很不走运,我的虫子很快就不会出现".
虽然除了马克之外的其他答案没有错,但他们也不完全正确.通过在程序中明确分配的内容之后访问数据,您正在做的是导致"未定义的行为".它可以做任何事情,包括"工作".
当我开始写这篇文章时,史蒂夫的回答并不存在.
它们都进行了越界数组访问 - 你有一个包含3个浮点指针的数组,你正在访问第8个数组.这肯定会崩溃.
但是,与Java或其他一些托管语言不同,每个阵列访问都没有明确的边界检查(因为它的性能成本太高).所以检查你的唯一界限是你的MMU.如果您最终访问不属于您的应用程序的内存,您将崩溃.如果你点击了未分配的内存,但仍然恰好是你的过程的一部分(例如,可能是一个保护词),它将默默地成功.对于非常难以追踪的错误,这是一个很好的秘诀.
界限检查是关键.尽可能做到.
| 归档时间: |
|
| 查看次数: |
2371 次 |
| 最近记录: |