为什么此代码不会导致内存泄漏
Why does this code not result in a memory leak?
我用--leak-check=full
valgrind
C++检查了以下代码,它说没有内存泄漏。为什么?
char *p = new char[256];
delete p;
据我所知,new[]
应该与delete[]
相匹配。
尽管正如@KillianDS所说,这是未定义的行为,但差异可能与delete
和delete[]
释放底层内存的事实有关。delete[]
的要点是在释放内存之前调用数组中每个对象的析构函数。由于char
是一个 POD,并且没有析构函数,因此在这种情况下,两者之间没有任何有效的区别。
但是,您绝对不应该依赖它。
p
指向基本数据类型(如 char 或 int)时,delete
和 delete[]
才会相等。
如果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
分配函数的标准部分,第3段说(强调我的):
[...]否则,如果提供给标准库中运算符 delete(void*) 的值不是以前调用标准库中运算符 new(std::size_t) 或运算符 new(std::size_t, constd::nothrow_t&) 返回的值之一,则行为未定义;如果提供给标准库中运算符 delete[] (void*) 的值不是以前调用的运算符 new[] (std::size_t) 或运算符 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()
来释放内存。这就是您没有泄漏的原因。由于分配的内存是使用 g++ 中的 free()
完全释放的。
但最佳做法是,如果您使用delete []
版本,则必须使用new []
。
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 尽管遵循了规则,内存泄漏在哪里
- 为什么调用堆栈数组会导致内存泄漏
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 使用模板类的自定义列表类型中的内存泄漏
- 为什么以下C++代码中存在内存泄漏?
- OpenCV 我应该使用智能指针来防止内存泄漏吗?
- 我是否生成线程并导致内存泄漏?
- 多线程程序中出现意外的内存泄漏
- 为什么此函数会导致内存泄漏?
- 在 C++ 库中使用cythonized python时内存泄漏
- 需要帮助查找内存泄漏
- 瓦尔格林德的内存泄漏使用新的
- 无法找出我的代码中的内存泄漏
- C++ 结构内部的unordered_map会导致内存泄漏问题吗?
- 可视化 使用 VS Code 查找C++应用程序中的内存泄漏
- Shared_ptr双链接列表内存泄漏
- C++ 在类中使用常量引用文本时 O2 内存泄漏