我有以下代码
#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 标记
答案 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
让我们更具体一点:
您的核心转储显然是因为您没有返回值。
delete o
是一个删除表达式,它最终只会调用你的运算符delete,只有当指针不为NULL时才会这样做。如上所述,它必须是有效的指针
答案 5 :(得分:1)
我原本以为你的构造函数没被调用的事实也是一个线索。因为当你运行它时你会遇到分段故障。 new Object()
会发生什么?您的内存已分配(这是您的operator new
),然后调用您的构造函数。你的构造函数如何调用?通过取消引用指向已分配内存的指针....
如果你存在operator new
,一切正常:从运行时获取内存,调用构造函数,调用operator delete
。如果你创建一个实际做事的operator new
,你会看到operator delete
(和你的构造函数)被调用。