我在我的程序中越来越多地使用指针,在阅读有关指针的过程中,我发现的每一个指南或教程都说不正确使用指针会产生“灾难性”结果。
现在,我遇到了一些大内存泄漏的情况,并且指针取消引用了错误的指针变量,返回了一个不正确的值,但除此之外没有发生任何“灾难性的”;像我的电脑和/或其他程序崩溃。
有人可以给我一个简单的代码示例,肯定会产生“灾难性”的结果,也许会有一些发生的事情,如果你不小心使用了那段代码?通过“灾难性”结果,我的意思是代码可能会干扰其他程序或操作系统,并可能使它们崩溃。
答案 0 :(得分:3)
有两种主要的灾难 - 悬挂指针和内存泄漏。
悬挂指针是指针存储的地址不是对象的地址:
T* first;
T* second; //somewhere in another piece of code
first = new T();
second = first;
delete first;
first = 0; //second still stores the address of an already deleted object
内存泄漏是指没有存储堆分配对象地址的指针:
T* object;
for( int i = 0; i < 10; i++ ) {
object = new T();
}
delete object; // now the first nine objects are unreacheable
悬空指针很糟糕,因为使用它们会导致未定义的行为 - 程序可能会崩溃或修改一些不相关的数据,这将导致以后出现问题。内存泄漏很糟糕,因为分配的内存无法重用,因此程序可能会在一段时间后内存不足。
答案 1 :(得分:3)
不正确的指针算法也可能导致灾难,因为获取边界错误会导致缓冲区溢出,并且缓冲区溢出会导致数据损坏,例如堆栈粉碎:
void test_fun(int i)
int x[5];
for (int *p = x; p < x+10; ++p) { // obvious error, some are more subtle
*p = i;
}
return; // execution may resume at address `i`, with entertaining results
}
当然,你可以在调用strcpy
或memcpy
[*]时犯同样的错误,你不必自己做指针运算。如果攻击者控制i
的值(可能是因为它是从输入文件读取的,并且攻击者制作了恶意文件),那么你可能会比手上的崩溃更糟糕。结合更多特定于平台的技巧,攻击者可能会安排返回i
最终执行攻击者提供的代码。
[*]或strncpy
,或strlcpy
,strcpy_s
或std::copy
。一旦你以某种方式得到了一个绑定的错误,那么将错误的绑定提供给边界检查函数仍然是错误的......
答案 2 :(得分:0)
有几种情况可以想到:
答案 3 :(得分:0)
我看到的最令人讨厌的是“延迟失败”,当错误地完成写入访问会损坏稍后使用的数据结构时,会产生完全不相关代码的错误输出。在调试过程中,您会观察到“机器的兴起” - 数据结构神秘地获得了从未分配过的错误值,这对程序员来说是这样。您可能正在搜索距其实际位置数千个LOC的错误。