Valgrind does not report memory leak on “delete ar

2020-03-31 16:54发布

After implementing the C++ code below, I ran valgrind --leak-check=full in order to check if there was any memory leak. The result was 0 bytes were in use at exit and no leaks are possible.

However, later I discovered that I've forgotten to use delete[] x instead of just delete x inside the destructor.

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.

I changed the code to delete[] and the valgrind output was the same (as expected). But now I'm confused: "Is there a problem with valgrind, or does delete really works fine for arrays even without the operator []?"

#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;
}

2条回答
何必那么认真
2楼-- · 2020-03-31 17:08

using delete without [] causes memory leak.

No, it causes Undefined Behavior.

Your program where you allocate using new [] and deallocate using delete has Undefined Behavior. 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.

查看更多
Summer. ? 凉城
3楼-- · 2020-03-31 17:13

The main difference between delete and delete[] is not about memory deallocation, but about destructor calls.

While formally undefined behavior, in practice it will more or less work... except that delete will only call the destructor of the first item.

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.

查看更多
登录 后发表回答