与C ++中的delete和free函数混淆[重复]

||                                                                                                                   这个问题已经在这里有了答案:                                                      
已邀请:
当为分配有
new
的对象调用
free()
时,不会调用其析构函数,因此在此示例中,您会发生内存泄漏。另外,在此示例中,必须使用
delete[]
,因为内存是由
new[]
分配的。     
是的,这是一个巨大的问题:任何人都可以覆盖
new
(和
delete
)的任何类型,并且可能会或可能不会将
malloc
用作基础分配器(实际上,它可能不会)。同时,C ++ 03标准的§20.4.6/ 4说明:   函数“ 0”不会通过调用“ 8”来尝试取消分配存储。 意思是,任何“ 1”调用都可以以任何方式分配内存,但是“ 0”很可能不会正确地释放它。     
如果使用new分配对象,则必须使用delete取消分配对象。 free()释放通过malloc等分配的内存块。     
除了分配和取消分配内存外,new运算符还调用ctor,而delete运算符则调用析构函数。函数malloc和free仅分别分配和释放内存。     
使用非返回值
malloc
calloc
的地址调用
free
是未定义的行为。显然,在您的示例中,不会调用
Foo
的析构函数,但是在某些方面,这是您最少的担心。从字面上看,任何事情都可能发生。 (在我自己的开发环境中,我使用调试
operator new
operator delete
operator new
返回的地址不是对
malloc
的调用返回的地址,并且调用
free
会产生各种各样的不良影响,包括可能破坏免费版。太空竞技场,造成以后的崩溃。)     
您的代码有两个问题: 显然第一个是自由/删除的混合 在C ++代码中,为避免混淆,最好不要使用malloc / free。但是如果必须的话,free()只能用于释放通过malloc / calloc / realloc创建的指针。传递任何其他指针,您的程序可能会繁荣起来。 给此问题增加更多上下文的是,C ++版本的new / delete不仅分配/释放内存,而且通过构造函数/析构函数初始化/取消初始化对象。析构函数比较模糊,因为它用于释放在构造函数中创建的资源。在您的情况下,构造函数分配内存,而析构函数分配内存。但是由于您使用的是免费的,因此不会调用任何析构函数(因此,每个单元中都有内存泄漏)。 您遇到的另一个问题是,当您在类中具有RAW指针时,编译器生成的复制构造函数和赋值运算符的版本(这是编译器可以为每个类自动生成的四个方法中的两个)不能很好地工作。 例如:
{
  Foo     a;        // a.x = pointer to a dynamically allocated location
  Foo     b(a);     // b.x = a.x (whoops)

} // Both a and b go out of scope here.
  // This means b\'s destructor is called
  // Followed by a\'s destructor (now here is where the problem is)
  // Because b.x = a.x you have now called delete on the same pointer twice.
不允许重复删除同一指针。 您需要做的就是查找“三法则” 但是基本上,当您的类包含RAW指针时,您还想确保所有的Copy Constructor / Assignment运算符/ Destructor都已定义。 因此,在分配内存时要记住的事情: new必须与删除匹配。 new []必须与delete []匹配。 free()只能用于malloc / calloc / realloc的结果 掌握了这些规则后: 尝试不要使用删除。 了解智能指针和容器(让它们为您工作)。 如果对象包含RAW指针(这种情况很少见,因为您已经了解了智能指针和容器)。您必须知道三个规则,以及如何确保编译器生成的方法不会意外使您的对象混乱。     

要回复问题请先登录注册