未调用运算符delete() 的类实现

发布于 2024-09-26 22:21:20 字数 1224 浏览 4 评论 0原文

我有以下代码

#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() 方法没有被调用。

任何人都可以阐明为什么它没有被调用吗?

感谢您针对我的全部大写咆哮关注核心转储,因为它实际上是问题所在。

编辑-- 好吧,我从哪里开始......我对咆哮感到非常抱歉。我们都经历过这样的情况,在按时完成任务的压力下,一些无害的事情似乎引起了问题,我们确信这是一回事,但实际上却是另一回事。 这给了我一个宝贵的教训......我需要开始倾听...... 我非常感谢这里提供的所有帮助和建议。

谢谢 标记。

I have the following code

#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;
}

and it produces this output...

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

and then core dumps.

Given that I don't get the output from the operator delete() method and that it core dumps. I'm assuming that my operator delete() method isn't being invoked.

Can anyone shed any light as to why it isn't being invoked?

Thank you for focusing on the core dump against my ALL CAPS RANTS because it actually turned out to be the problem.

EDIT--
Ok, Where do I start.... I'm incredibly sorry for ranting. We've all been there, under pressure to meet a deadline and something innocuous appears to be causing an issue and we're convinced it's one thing when in fact it's another.
This has taught me a valuable lession... I need to start listening....
I fully appreciate all of help and advice given here.

Thx
Mark.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

天邊彩虹 2024-10-03 22:21:20

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

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

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

Your new expression does two things. It invokes the appropriate operator new function to allocate some memory and then constructs a new Object in the memory pointed to by the return value of operator new.

As you don't have a return statement in your operator new you get undefined behaviour. If we explore what is likely to happen, it is likely that the function returns a random value for the return value and the compiler attempts to construct the Object (including its owned std::string) at an invalid address.

This will cause a crash before your code ever reaches the delete statement.

灵芸 2024-10-03 22:21:20

operator new 必须返回一个指向足够内存的指针(或抛出异常),因为 new 表达式还将尝试为分配的内存调用 Object 的构造函数。问题不在于 delete,而是 new Object 无法正常完成。

operator new must return a pointer to sufficient memory (or throw an exception), because the new-expression will also be trying to invoke the constructor of Object for the allocated memory. The problem is not with delete, it's new Object that cannot complete normally.

我三岁 2024-10-03 22:21:20

如果我将 main 更改为 be

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 永远不会被调用..这是因为您遇到了未定义的行为。 (特别是在许多编译器上,构造函数似乎在未定义的位置被调用)

new 更改为 be,

   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。

If I change main to be

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;
}

then I get

static void* Object::operator new(size_t) : bytes = 4
Bus error

and cout is never called.. This is because you are running into undefined behaviour. (In particular it looks like on many compilers the constructor is being called in the location that is undefined)

If I change new to be

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

I get

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

so delete will be called if you do the right thing.

五里雾 2024-10-03 22:21:20

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

You're crashing well before delete() is called, because you haven't allocated any storage for std::string x; - if you comment out this instance variable then the code should compile (with warnings) and run OK.

把时间冻结 2024-10-03 22:21:20

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

另一方面,如果正如您所说,这是一个示例,那么也许您从 new 返回了 0,在这种情况下,不会调用运算符删除,因为在 0 指针上调用删除相当于空语句。

malloc new 中的某些内容并返回它,并且将调用运算符删除

让我们在这里更具体一些:

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

  2. delete o 是一个删除表达式,它只会最终调用您的运算符delete,并且仅当指针不为 NULL 时才会执行此操作。如前所述,它必须是一个有效的指针

Why doesn't your operator new return a value? It is declared to return void * but dosn't return anything. This means your compiler should have given a compile error, apparently it didn't, and well the crash may be becaue of that.

On the other hand, if this, as you say, is an example, then maybe you returned 0 from new, in which case operator delete is not being invoked because calling delete on a 0 pointer is equivaent to an empty statement.

malloc something in new and return it, and operator delete will be invoked

Let's be more specific here:

  1. Your core dump is obviously because you don't return a value.

  2. delete o is a delete expression which will only eventually call your operator delete, and it will do so ONLY if the pointer is not NULL. As said, it must be a valid pointer

梦与时光遇 2024-10-03 22:21:20

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

如果您将operator new存根,一切都会正常:您从运行时获取内存,调用构造函数,操作符delete 被调用。如果您创建一个实际执行操作的operator new,您将看到operator delete(以及您的构造函数)也被调用。

I would have thought that the fact your constructor wasn't being called either was a bit of a clue. As is the fact that you've got a segmentation fault going on when you run it. What happens with new Object()? Your memory is allocated (this is your operator new) and then your constructor is called. How is your constructor called? By dereferencing the pointer to your allocated memory....

If you stub out your operator new, everything works fine: you get the memory from the runtime, the constructor is called, the operator delete is called. If you make an operator new that actually does things, you'll see operator delete (and your constructor) getting called too.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文