delete与析构函数的显式调用 >在C++中调用删除>代码>在分配为新< /COD>的对象中调用类的析构函数,并释放内存。如果不是删除对象,而是显式调用其析构函数,然后释放内存,会有什么区别吗

delete与析构函数的显式调用 >在C++中调用删除>代码>在分配为新< /COD>的对象中调用类的析构函数,并释放内存。如果不是删除对象,而是显式调用其析构函数,然后释放内存,会有什么区别吗,c++,language-lawyer,destructor,C++,Language Lawyer,Destructor,例如,考虑以下示例 #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; } 使用valgrind/memcheck运行程序时会出现一个不匹配的f

例如,考虑以下示例

#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;
}
使用
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
    是否完全等同于调用析构函数和
    免费
    ?标准是否规定了这一点,或者我遇到了UB 用上面的代码

虽然显式调用析构函数是合法的,但您希望这样做的情况非常罕见(例如,在较大的缓冲区中构造和销毁对象的std::vector)


请注意,您应该始终将分配器与适当的内存释放、malloc/free、new/delete等进行匹配。虽然运算符new()通常依赖malloc,但并不要求它这样做,在这种情况下,您的不匹配将产生未定义的结果。

将非空指针传递到
free()如果指针不是由
malloc()
calloc()
realloc()
返回,则给出未定义的行为。因此,您对
free()
的调用具有未定义的行为。另外:。@francesco但您的问题也有很多答案。例如,请参阅我以前的评论,其中包含复制粘贴链接。根本无法保证
new
使用
malloc
/
calloc
/
realloc
@DanielLangr,我不认为这是重复的。此问题知道dtor,但要求dtor+
free
vs
delete
。这是不同的…@m8mble如果这个问题在别处得到了回答,尽管另一个问题的提问方式不同,那么它是重复的。尽管我们可能会争论:)。但答案是一样的。顺便说一句,这两个问题都解决了同一个问题。不调用析构函数不一定是个问题;参见,例如。
==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)