2010-02-28 28 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的析構函數。

相關問題