没有调用operator delete()的类实现

时间:2010-10-12 09:07:30

标签: c++ operator-overloading

我有以下代码

#include <iostream>
#include <cstddef>
#include <string>
#include <memory>


class Object
{
public:
       Object()
       {
               std::cout << __PRETTY_FUNCTION__ << std::endl;
       }
       std::string x;

       void *operator new( size_t bytes )
       {
               std::cout << __PRETTY_FUNCTION__ << " : bytes = " << bytes << std::endl;
       }

       void operator delete( void * arg )
       {
               std::cout << __PRETTY_FUNCTION__ << std::endl;
       }
};



int main( int c, char *v[] )
{
       // std::auto_ptr< Object > pObject( new Object() );
       Object *o = new Object();
       delete o;
}

并产生此输出......

static void* Object::operator new(size_t) : bytes = 8

然后是核心转储。

鉴于我没有从运算符delete()方法获得输出并且它没有核心转储。我假设我的操作符delete()方法没有被调用。

任何人都可以解释为什么不调用它?

感谢您专注于针对我的ALL CAPS RANTS的核心转储,因为它实际上是问题所在。

EDIT-- 好的,我从哪里开始.... 我非常抱歉咆哮。我们都在那里,在压力下遇到截止日期,无关紧要的东西似乎引起了一个问题,我们确信这是一回事,事实上它是另一回事。 这教会了我一个有价值的东西......我需要开始倾听...... 我非常感谢这里提供的所有帮助和建议。

THX 标记

6 个答案:

答案 0 :(得分:9)

你的new表达式做了两件事。它调用适当的operator new函数来分配一些内存,然后在Object的返回值所指向的内存中构造一个新的operator new

由于您在operator new中没有返回语句,因此您获得未定义的行为。如果我们探索可能发生的情况,则函数可能会返回返回值的随机值,并且编译器会尝试在无效地址处构造Object(包括其拥有的std::string)。

这将导致在代码到达delete语句之前发生崩溃。

答案 1 :(得分:5)

operator new 必须返回指向足够内存的指针(或抛出异常),因为new-expression也会尝试为已分配的内存调用Object的构造函数。问题不在于delete,而new Object无法正常完成。

答案 2 :(得分:3)

如果我将主要改为

int main( int c, char *v[] )
{
       // std::auto_ptr< Object > pObject( new Object() );
       Object *o = new Object();
       std::cout<<"I'm ok here"<<std::endl;
       delete o;
}

然后我得到

static void* Object::operator new(size_t) : bytes = 4
Bus error
永远不会调用

和cout ..这是因为您遇到了未定义的行为。 (特别是在许多编译器中,构造函数在未定义的位置被调用)

如果我将新的更改为

   void *operator new( size_t bytes )
   {
           std::cout << __PRETTY_FUNCTION__ << " : bytes = " << bytes << std::endl;
          return new char[bytes];
   }

我得到了

static void* Object::operator new(size_t) : bytes = 4
Object::Object()
I'm ok here
static void Object::operator delete(void*)

如果你做对了,那么就会调用delete。

答案 3 :(得分:2)

在调用delete()之前你崩溃了,因为你没有为std::string x;分配任何存储 - 如果你注释掉这个实例变量,那么代码应该编译(带警告)并运行OK。

答案 4 :(得分:1)

为什么您的运算符new不返回值?它被声明返回void *但是不返回任何东西。这意味着你的编译器应该给出一个编译错误,显然它没有,并且崩溃可能就是这样。

另一方面,如果这是一个例子,那么也许你从new返回0,在这种情况下,不调用operator delete,因为在0指针上调用delete等同于空语句。

malloc new in new并返回它,并且将调用operator delete

让我们更具体一点:

  1. 您的核心转储显然是因为您没有返回值。

  2. delete o是一个删除表达式,它最终只会调用你的运算符delete,只有当指针不为NULL时才会这样做。如上所述,它必须是有效的指针

答案 5 :(得分:1)

我原本以为你的构造函数没被调用的事实也是一个线索。因为当你运行它时你会遇到分段故障。 new Object()会发生什么?您的内存已分配(这是您的operator new),然后调用您的构造函数。你的构造函数如何调用?通过取消引用指向已分配内存的指针....

如果你存在operator new,一切正常:从运行时获取内存,调用构造函数,调用operator delete。如果你创建一个实际做事的operator new,你会看到operator delete(和你的构造函数)被调用。