什么是这些所谓的“灾难”,不正确使用指针会导致什么?

时间:2010-12-22 10:52:42

标签: c++ memory pointers memory-management unsafe-pointers

我在我的程序中越来越多地使用指针,在阅读有关指针的过程中,我发现的每一个指南或教程都说不正确使用指针会产生“灾难性”结果。

现在,我遇到了一些大内存泄漏的情况,并且指针取消引用了错误的指针变量,返回了一个不正确的值,但除此之外没有发生任何“灾难性的”;像我的电脑和/或其他程序崩溃。

有人可以给我一个简单的代码示例,肯定会产生“灾难性”的结果,也许会有一些发生的事情,如果你不小心使用了那段代码?通过“灾难性”结果,我的意思是代码可能会干扰其他程序或操作系统,并可能使它们崩溃。

4 个答案:

答案 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
}

当然,你可以在调用strcpymemcpy [*]时犯同样的错误,你不必自己做指针运算。如果攻击者控制i的值(可能是因为它是从输入文件读取的,并且攻击者制作了恶意文件),那么你可能会比手上的崩溃更糟糕。结合更多特定于平台的技巧,攻击者可能会安排返回i最终执行攻击者提供的代码。

在任何人开始之前,

[*]或strncpy,或strlcpystrcpy_sstd::copy。一旦你以某种方式得到了一个绑定的错误,那么将错误的绑定提供给边界检查函数仍然是错误的......

答案 2 :(得分:0)

有几种情况可以想到:

  • 在他们离开范围后继续访问free()/ delete()d内存或局部变量
  • 由于所有权不明确导致堆内存泄漏
  • 对数据的意外共享访问,其中对指向值的更改可能会混淆一些处理它们的算法
    • 意外的浅拷贝
  • 由于假定POD数据的天真二进制写入实际包含指向其他数据的指针而导致序列化不完整/有缺陷
  • 共享内存中的多进程不安全数据,其中指针(尤其是虚拟分派指针)在访问它的不同进程中需要不同
  • 循环数据链接导致代码无限期地陷入循环
  • 通过数据移动指针,使得它们意外地移出数据(问题类似于数组索引,但更复杂,因为不一定有任何常量引用和始终安全的相对索引范围)
  • 未能正确检查/处理哨兵值
  • 指针所指向的数据类型的问题
    • 使用不安全/错误的演员表(例如需要动态演员表的重新演绎演员表)
    • 没有意识到指针的索引是以指针类型的大小为单位完成的
    • 指向/来自较短整数类型的指针的无效转换

答案 3 :(得分:0)

我看到的最令人讨厌的是“延迟失败”,当错误地完成写入访问会损坏稍后使用的数据结构时,会产生完全不相关代码的错误输出。在调试过程中,您会观察到“机器的兴起” - 数据结构神秘地获得了从未分配过的错误值,这对程序员来说是这样。您可能正在搜索距其实际位置数千个LOC的错误。