1

在实现了下面的 C++ 代码之后,我跑来valgrind --leak-check=full检查是否有任何内存泄漏。结果是退出时使用了 0 个字节,并且 不可能发生泄漏

但是,后来我发现我忘记了使用delete[] x,而不仅仅是delete x在析构函数内部。

我搜索了一些解释(例如:C++ 中的 delete vs delete[] 运算符),我读到的所有内容都说使用deletewithout[]会导致内存泄漏,因为它只调用数组中第一个对象的析构函数。

我将代码更改为 delete[] 并且 valgrind 输出是相同的(如预期的那样)。但现在我很困惑:“valgrind 有问题吗,或者delete即使没有操作符,数组真的可以正常工作[]?”

#include <iostream>
#include <string.h>
using namespace std;
class Foo {
  private: char *x;
  public:
    Foo(const char* px) {
       this->x = new char[strlen(px)+1];
       strcpy(this->x, px);
    }
    ~Foo() {
       delete x;
    }
    void printInfo() {  cout << "x: " << x << endl;  }
};
int main() {
   Foo *objfoo = new Foo("ABC123");
   objfoo->printInfo();
   delete objfoo;
   return 0;
}
4

2 回答 2

7

使用不带 [] 的 delete 会导致内存泄漏。

不,它会导致Undefined Behavior

您分配使用new []和取消分配使用的程序delete具有未定义的行为。实际上,您很幸运(相当不幸)它没有表现出一些奇怪的行为。

作为旁注,您还需要为您的班级遵循三原则。目前,您不这样做,并且在不久的将来会找麻烦。

于 2012-05-14T15:12:41.057 回答
3

delete和之间的主要区别delete[]不是关于内存释放,而是关于析构函数调用。

虽然形式上是未定义的行为,但实际上它或多或少会起作用……除了delete只会调用第一项的析构函数。

作为旁注,您可能会遇到一个问题:

#include <iostream>

struct A{
  ~A() { std::cout << "destructor\n"; }
};

int main() {
  A* a = new A[10];
  delete a;
}

有一点像:

*** glibc detected *** ./prog: munmap_chunk(): invalid pointer: 0x093fe00c ***
======= Backtrace: =========
/lib/libc.so.6[0xb759dfd4]
/lib/libc.so.6[0xb759ef89]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/libstdc++.so.6(_ZdlPv+0x21)[0xb77602d1]
./prog(__gxx_personality_v0+0x18f)[0x8048763]
./prog(__gxx_personality_v0+0x4d)[0x8048621]
======= Memory map: ========

在ideone看到它。

于 2012-05-14T15:44:45.730 回答