Segfault, когда я удаляю объект - GDB говорит в free () - PullRequest
3 голосов
/ 01 марта 2010

Я работаю над заданием для работы в сети, где мы должны создать сетевую библиотеку на 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");
}

Унаследованный класс и деструктор:

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

Когда я запускаю свою программу, она вызывает ошибку в строке delete 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 ]

4 голосов
/ 01 марта 2010

строковые объекты не были размещены с использованием оператора new. Не удаляйте их, они будут автоматически освобождены

2 голосов
/ 01 марта 2010

Это неправильно:

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

Деструкторы для содержащихся в них объектов-членов автоматически вставляются в деструктор содержащего класса. Кроме того, вы не new их, не так ли, так почему delete?

0 голосов
/ 01 марта 2010

Сегфоут в пределах free() или malloc() обычно означает, что вы как-то повредили кучу, либо освободив что-то более одного раза, либо освободив то, что никогда не было выделено. Фактическая ошибка почти никогда не возникает там, где происходит ошибка.

Ваша ошибка, как указывали другие, delete * * * * * членов вашего класса. Память для этих членов (игнорируя любую память, которую они могли бы динамически распределить внутри) не была выделена отдельным вызовом malloc / new, и поэтому, когда вы освобождаете их, вы запутываете кучу. Как указывает @Nikolai, соответствующий деструктор запускается автоматически.

Однако, если вы заявили следующее:

class Foo {
    string *s1;
};

тогда вам нужно будет delete this->s1 в деструкторе Фу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...