2010-02-28 33 views
3

我正在为网络的工作,我们应该在C中创建一个网络库,然后在我们的C++程序中使用它。我的C++没有C那么强大,所以我首先着手解决所有出现的问题,然后向您介绍我的第一个问题。 :DSegfault当我删除一个对象 - GDB说在免费()

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

基类的头和析构函数:

// 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"); 
} 

继承类和析构函数:当我尝试删除一个类的对象

// 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

回答

4

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

+0

所以我只能删除我用new创建的对象呢?就他们被自动释放而言,只有在退出程序或调用类析构函数时才会发生? – Chris 2010-02-28 23:39:52

+0

@Chris基本上会发生什么是每个成员变量的析构函数都被对象析构函数调用,否则不需要显式破坏(除非使用原始指针)。一般来说,是删除新的,但要小心你使用新的[],因为那么你必须使用删除[] – Anycorn 2010-02-28 23:50:43

+0

@Chris:一般规则是 - 无论它带来的存在(malloc,new,new [ ],隐式通过堆栈) - 你必须使用相反的(自由,删除,删除[],隐式通过堆栈)。 – crazyscot 2010-02-28 23:54:57

2

释放这是错误的:

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

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

0

free()malloc()中的段错误通常意味着您以某种方式破坏了堆,或者通过多次释放某个东西或释放一些从未分配过的东西。实际的错误几乎不会发生段错误。

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

然而,如果你已经宣布:

class Foo { 
    string *s1; 
}; 

那么你就需要在delete this->s1 Foo的析构函数。

相关问题