valgrind
我用with检查了以下 C++ 代码,--leak-check=full
它说没有内存泄漏。这是为什么?
char *p = new char[256];
delete p;
new[]
delete[]
据我所知,应该匹配。
valgrind
我用with检查了以下 C++ 代码,--leak-check=full
它说没有内存泄漏。这是为什么?
char *p = new char[256];
delete p;
new[]
delete[]
据我所知,应该匹配。
delete
尽管正如@KillianDS 所说,这是未定义的行为,但差异可能与两者都delete[]
释放底层内存的事实有关。关键delete[]
是在释放内存之前调用数组中每个对象的析构函数。由于char
是POD并且没有析构函数,因此在这种情况下,两者之间没有任何有效区别。
但是,您绝对不应该依赖它。
delete
并且delete[]
仅当p
指向基本数据类型(例如 char 或 int)时才相等。
如果p
指向一个对象数组,结果会有所不同。试试下面的代码:
class T {
public:
T() { cout << "constructor" << endl; }
~T() { cout << "destructor" << endl; }
};
int main()
{
const int NUM = 3;
T* p1 = new T[NUM];
cout << p1 << endl;
// delete[] p1;
delete p1;
T* p2 = new T[NUM];
cout << p2 << endl;
delete[] p2;
}
通过使用delete[]
数组中 T 的所有析构函数将被调用。通过使用delete
只有p[0]
' 的析构函数将被调用。
当我尝试这个时,valgrind 报告:
==22707== Mismatched free() / delete / delete []
==22707== at 0x4C2B59C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22707== by 0x40066D: main (in /home/andrew/stackoverflow/memtest)
==22707== Address 0x5a1a040 is 0 bytes inside a block of size 256 alloc'd
==22707== at 0x4C2C037: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==22707== by 0x40065D: main (in /home/andrew/stackoverflow/memtest)
这并不是真正的内存泄漏,但 valgrind 确实注意到了这个问题。
因为它是未定义的行为。在您的情况下,delete
可能会delete []
在您的编译器中完成工作,但它可能无法在另一台机器上工作。
这是未定义的行为,因此我们无法推断其行为。如果我们查看草案 C++ 标准部分3.7.4.2
Deallocation functions,第3段说(强调我的):
[...]否则,如果在标准库中提供给 operator delete(void*) 的值不是先前调用 operator new(std::size_t) 或 operator new 返回的值之一,则行为未定义(std::size_t, conststd::nothrow_t&) ,如果提供给标准库中 operator delete[] (void*) 的值不是先前调用返回的值之一,则行为未定义标准库中的 operator new[] (std::size_t) 或 operator new[] (std::size_t, const std::nothrow_t&)。
实际的细节将是实现定义的行为,并且可能会有很大差异。
delete
和之间的区别在于delete []
编译器添加代码来调用析构函数来删除对象。说这样的话:
class A
{
int a;
public:
...
~A() { cout<<"D'tor"; }
};
a=new A[23];
delete [] a;
这delete [] a;
被转换为类似的东西,
for (int i=0; i<23; i++)
{
a[i].A::~A();
}
std::delete a;
因此,对于您的情况,由于它是内置数据类型,因此无需调用析构函数。所以,它变成了,
std::delete a;
哪个实习生调用free()
来释放内存。这就是你没有得到任何泄漏的原因。free()
由于分配的内存使用g++完全释放。
但最佳做法是,delete []
如果您使用new []
.