在C++中,使用
例如,考虑以下示例。
new
分配的对象调用delete
会调用类的析构函数并释放内存。如果不使用delete
删除对象,而是显式调用其析构函数然后释放内存,是否会有任何区别?例如,考虑以下示例。
#include <iostream>
struct A {
int i;
~A() { std::cout << "Destructor, i was " << i << std::endl; }
};
int main()
{
A* p = new A{3};
p->~A();
free(p);
return 0;
}
使用 g++
7.3.0 和 clang
6.0.1 编译代码,并使用 -Wextra -Wall -pedantic
标志,不会引发任何警告。
程序的输出如预期所示。
Destructor, i was 3
使用valgrind
/memcheck
运行程序时出现了不匹配的free/delete错误:
==27743== Memcheck, a memory error detector
==27743== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==27743== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==27743== Command: ./destructor
==27743==
Destructor, i was 3
==27743== Mismatched free() / delete / delete []
==27743== at 0x4C3033B: free (vg_replace_malloc.c:530)
==27743== by 0x4009FC: main (in /tmp/destructor)
==27743== Address 0x5bbac80 is 0 bytes inside a block of size 4 alloc'd
==27743== at 0x4C2F77F: operator new(unsigned long) (vg_replace_malloc.c:334)
==27743== by 0x4009DA: main (in /tmp/destructor)
==27743==
==27743==
==27743== HEAP SUMMARY:
==27743== in use at exit: 0 bytes in 0 blocks
==27743== total heap usage: 3 allocs, 3 frees, 73,732 bytes allocated
==27743==
==27743== All heap blocks were freed -- no leaks are possible
==27743==
==27743== For counts of detected and suppressed errors, rerun with: -v
==27743== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
然而,这里没有内存泄漏。
我当然知道在上面的代码中处理对象p
的标准方法是调用delete
。
我的问题更多是形式上的:
delete
是否完全等同于调用析构函数和free
?标准是否指定了这一点,或者我在上面的代码中遇到了UB(未定义行为)?
free()
的指针不是由malloc()
、calloc()
或realloc()
返回的非空指针,则会产生未定义的行为。因此,您调用free()
的行为是未定义的。 - Peterfree
与delete
的区别。那是不同的... - m8mble