悬空指针和内存泄漏有什么区别?

时间:2015-03-14 14:25:01

标签: c++11 memory-leaks dynamic-allocation dangling-pointer

我是C ++的新手,想问下面的代码是否是悬空指针或内存泄漏的一个例子,因为它指向动态分配的数组:

int * n = new int[10];
for (int prev = 0; prev < 10; prev++) {
    *n = *(n + prev + 1);
}
delete[] n;
n = nullptr;

3 个答案:

答案 0 :(得分:13)

悬空指针是一个指向没有对象所在地址的指针。即它指向无效的记忆。 “悬空”这个词通常带有以下含义,指向有效的东西,以及某些东西被破坏(因为它被明确解除分配或者因为它超出了范围)。

当您丢失动态分配的内存时,会发生内存泄漏;也就是说,当你“忘记”指向该内存的最后一个指针时,意味着你不能再解除分配它。如果在调用n = nullptr;之前delete[] n; {1},则代码会产生内存泄漏。

如果我 用这两个术语中的一个来描述你的情况,那就是“悬挂指针”,只是因为你在最后一次迭代中超越了缓冲区。但是,我通常不会称之为“悬空指针”,因为它首先从未有效。我称之为“缓冲区溢出”或“越界访问”。

答案 1 :(得分:8)

  

悬空指针与内存泄漏有什么区别?

你可以说悬空指针与内存泄漏相反。

一个指针不指向有效内存,一个是没有指向的有效内存。

(但正如其他答案指出的那样,你的代码都不是。)

答案 2 :(得分:6)

让我们先做一些规范的例子:

内存泄漏

int *x;
x = new int;
x = nullptr;

我们在堆上分配了一个整数,然后我们丢失了它的跟踪。此时我们无法在该整数上调用delete。这是内存泄漏。

悬空指针

int *x;
x = new int;
delete x;

x现在是一个悬垂的指针。它指向曾经是有效记忆的东西。如果我们此时使用*x,我们将访问我们不应该访问的内存。通常,为了解决这个问题,在delete x;之后,我们会x = nullptr;

您的代码

您的代码有一个不同的问题,我将减少您的代码,以便我们可以更轻松地谈论同样的事情:

int *x;
x = new int[10];
x[9] = x[10];

我会将此描述为以上两种情况。这是一个缓冲区溢出。