删除对象时的Segfault - GDB在free()中说

时间:2010-02-28 23:28:01

标签: c++ c memory memory-management

我正在进行网络分配,我们应该在C中创建一个网络库,然后在我们的C ++程序中使用它。我的C ++并不像我的C那么强大,所以我首先开始这样做,这样我就可以解决任何问题,并向你展示我的第一个问题。 :d

我有一个基类和一个继承的类(最终会有另一个继承的类),它将提供确定服务器行为的函数。

基类标题和析构函数:

    // Message Forwarder Base Class 
class MessageForwarder
{
public:
    /* ------ Public Function Declarations ------ */
    MessageForwarder(const string serverName, const string serverAddress);
    virtual ~MessageForwarder();
    virtual void Print() const = 0; 

protected:
    /* ------ Private Variable Declarations ------ */
    string monitor; // 192.168.1.102:8000 - The address to the monitoring server
    string myName; // The name of message forwarding server
    string myAddress; // The address of the message forwarding server
};    

MessageForwarder::~MessageForwarder()
{
    delete &this->monitor;
    delete &this->myName;
    delete &this->myAddress;
    fprintf(stdout, "Cleaning up MessageForwarder\n");
}

继承的Class和析构函数:

// Client Message Forwarder Derived Class
class ClientMessageForwarder : public MessageForwarder
{
public:
    /* ------ Public Function Declarations ------ */
    ClientMessageForwarder(const string serverName, const string serverAddress);
    ~ClientMessageForwarder();
    void Print() const; 

private:
    /* ------ Private Variable Declarations ------ */

};

ClientMessageForwarder::~ClientMessageForwarder()
{
    fprintf(stdout, "Cleaning up ClientMessageHandler\n");
}

当我尝试删除一个类对象时,我的问题出现了。我的计划如下:

int main(int argc, char *argv[])
{
    /* ------ Variable Declarations ------ */

// Server Object
MessageForwarder *msgFrwder;

msgFrwder = new ClientMessageForwarder(serverName, serverAddress);
msgFrwder->Print();
delete msgFrwder; <------------ SEGFAULT here!

return 0;}

当我继续运行我的程序时,会删除行删除msgFrwder;我继续使用带有转储核心的GDB并询问它发生在哪里,它给了我以下内容:

#0  0x0000000800afe409 in free () from /lib/libc.so.7
#1  0x00000008006cbd17 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string () from /usr/lib/libstdc++.so.6
#2  0x0000000000401e88 in ~MessageForwarder (this=0x800d02080) at ./classes/msgfrwd.cpp:44
#3  0x00000000004023c5 in ~ClientMessageForwarder (this=0x800d02080) at ./classes/climsgfrwd.cpp:44
#4  0x000000000040158c in main (argc=7, argv=0x7fffffffe478) at ./msgfrwdserver.cpp:97

凭借我有限的C ++知识,我觉得我正在按照正确的步骤清理并释放我的记忆。当我运行我的程序时,它确实输出“清理MessageForwarder”,所以我知道它执行了该行。

我已经搜索了解决方案,并在一段时间内解决了这个问题,但无法找到解决方案。任何帮助都会非常感激,或者解释实际发生的事情以及发生段错误的原因会有所帮助。

感谢您的帮助。它赞赏。 :d

3 个答案:

答案 0 :(得分:4)

未使用new运算符分配字符串对象。不要删除它们,它们将被自动释放

答案 1 :(得分:2)

这是错误的:

MessageForwarder::~MessageForwarder()
{
    delete &this->monitor;
    delete &this->myName;
    delete &this->myAddress;
    fprintf(stdout, "Cleaning up MessageForwarder\n");
}

包含的成员对象的析构函数会自动插入到包含类析构函数中。此外,你没有new他们,是吗,为什么delete

答案 2 :(得分:0)

free()malloc()中的段错误通常意味着您已经以某种方式损坏了堆,无论是通过多次释放某些内容,还是释放从未分配过的内容。实际的错误几乎不会发生段错误。

正如其他人所指出的,您的错误是delete您班级的string成员。这些成员的内存(忽略它们可能在内部动态分配的任何内存)不是通过单独调用malloc / new来分配的,所以当你释放它们时就会搞乱堆。正如@Nikolai指出的那样,他们适当的析构函数会自动运行。

但是,如果您声明了以下内容:

class Foo {
    string *s1;
};

然后你需要在Foo的析构函数中delete this->s1