简体   繁体   English

Valgrind不报告“删除数组”上的内存泄漏

[英]Valgrind does not report memory leak on “delete array”

After implementing the C++ code below, I ran valgrind --leak-check=full in order to check if there was any memory leak. 在实现下面的C ++代码之后,我运行valgrind --leak-check=full来检查是否有任何内存泄漏。 The result was 0 bytes were in use at exit and no leaks are possible . 结果是在出口处使用了0个字节,并且不可能泄漏

However, later I discovered that I've forgotten to use delete[] x instead of just delete x inside the destructor. 但是,后来我发现我已经忘记使用delete[] x而不是仅仅在析构函数中delete x了。

I searched for some explanations (for instance: delete vs delete[] operators in C++ ), and everything I read said that using delete without [] can cause memory leak, since it calls just the destructor for the first object in the array. 我搜索了一些解释(例如: C ++中的delete vs delete []运算符 ),并且我读到的所有内容都说使用不带[] delete可能会导致内存泄漏,因为它仅调用数组中第一个对象的析构函数。

I changed the code to delete[] and the valgrind output was the same (as expected). 我将代码更改为delete [],并且valgrind输出是相同的(与预期的一样)。 But now I'm confused: "Is there a problem with valgrind, or does delete really works fine for arrays even without the operator [] ?" 但是现在我很困惑: “ 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;
}

using delete without [] causes memory leak. 使用不带[]的删除会导致内存泄漏。

No, it causes Undefined Behavior . 不,它会导致Undefined Behavior

Your program where you allocate using new [] and deallocate using delete has Undefined Behavior. 您使用new []分配并使用delete取消分配的程序具有未定义的行为。 Actually, you are lucky(rather unlucky) it doesn't show some weird behavior. 实际上,您很幸运(而不是幸运),它没有表现出一些奇怪的行为。

As a side note, You also need to follow the Rule of Three for your class. 附带说明,您还需要在课堂上遵循三规则 Currently, you don't do so and are calling for trouble in near future. 目前,您还没有这样做,并且在不久的将来会遇到麻烦。

The main difference between delete and delete[] is not about memory deallocation, but about destructor calls. deletedelete[]之间的主要区别不在于内存释放,而在于析构函数调用。

While formally undefined behavior , in practice it will more or less work... except that delete will only call the destructor of the first item. 尽管是形式上未定义的行为 ,但实际上它会或多或少地起作用……除了delete只会调用第一项的析构函数。

As a side note, you may get an issue: 附带说明,您可能会遇到问题:

#include <iostream>

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

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

a bit like: 有一点像:

*** 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: ========

See it at ideone . ideone上看到它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM