2014-11-09 5 views
0

У меня есть строка кода в нижеприведенной программе, которая создает утечку памяти, и я не знаю, почему это так ...Почему моя функция создает утечку памяти? (C++)

Строка кода, где создается утечка.

Question* newQuestion = new Question(text, mark, answers, numAnswers, &this->operator[](qNum-1)); 

Вставляет новый узел в связанный список. Нужно ли мне удалить указатель «newQuestion» после того, как он находится в списке? Разве это не испортит мой список?

Остальная часть списка выглядит как разрушена через деструкторы, когда я запускаю ее через отладчик. Я просто не могу понять, почему эта ссылка не исчезает.

Не уверен, что я должен опубликовать остальную часть кода или нет, поскольку он немного длинный ... Я надеюсь, что это может быть просто очевидным, что я пропал без вести как начинающий C++.

Метод в целом является:

bool Exam::ReplaceDeleteQuestion(){ 
int qNum; 
char repDel; 
Question* temp = phead; 

cout << "Which question would you like to modify? Please enter the number (1, 2, ...)" <<endl; 
cin >> qNum; 

for(int i = 0; i<(qNum - 1); i++){ 
    if(temp == NULL || temp->GetNext() == NULL){ 
     cout << "Please enter an element within the bounds of the linked list"<<endl; 
     return true; 
    } 
    temp = temp->GetNext(); 
} 

cout << "Do you want to Replace or Delete? (R = Replace, D = Delete): "; 
cin >> repDel; 

while(repDel != 'R' && repDel != 'r' && repDel != 'D' && repDel != 'd'){ 
    cout << "Try again: R = Replace, D = Delete: "; 
    cin >> repDel; 
} 

//Set up new question and replace 
if(repDel == 'r' || repDel == 'R'){ 

    char* questionBuffer = new char[200]; 
    cout << "Please enter the new question text below"<<endl; 
    cin.ignore(200, '\n'); //Ignore newline character 
    cin.getline(questionBuffer, 200); 
    char* text = new char[strlen(questionBuffer) + 1]; 
    strcpy_s(text, strlen(questionBuffer)+1, questionBuffer); //Copy questionBuffer into text field 
    delete[] questionBuffer; //free question buffer 

    cout << "Please enter the new question mark: "<<endl; 
    int mark; 
    cin >> mark; 
    cout << "How many answers are there now? : "; 
    int numAnswers; 
    cin >> numAnswers; 

    Answer **answers = new Answer*[numAnswers]; //Allocate memory for the answer member 

    for(int i = 0; i < numAnswers; i++){ 
     cout << "Please enter answer " << i+1 <<endl; //Prompt user for text 
     answers[i] = new Answer(); //Create the answer 
    } 

    Question* newQuestion = new Question(text, mark, answers, numAnswers, &this->operator[](qNum-1)); 

    this->operator[](qNum-1) = *newQuestion; 

    delete[] answers; 
    //delete[] text; 


    return true; 
} 

ч файл

#ifndef QUESTION_H_ 
    #define QUESTION_H_ 

    #include <iostream> 

    // Question.h 
    class Question 
{ 
    char* text; 
    unsigned int mark; 
    Answer** answers; 
    unsigned int numAnswers; 
    Question* pNext; 
public: 
    Question():text(0),mark(0),answers(0),numAnswers(0),pNext(0){}; 
    Question(char*, unsigned int, Answer**, unsigned int, Question*); 
    Question(Question&); 
    ~Question(); 

    Question*& GetNext() 
    { 
     return pNext; 
    } 
    Answer& operator[](unsigned int i);   //overloaded indexing 
    Question& operator=(Question&);    // overloaded assignment 
    friend ostream& operator<<(ostream&, Question&); // overloaded insertion 
}; 

#endif 
+0

Вы размещаете объект в куче (по непонятным причинам). Затем скопируйте этот объект в любой 'this-> operator [] (qNum-1)'. Исходный объект никогда не используется снова и, в частности, никогда не освобождается. –

+1

Использование 'std :: string' и' std :: vector' и утечек памяти волшебным образом исчезнет. Я не стал подробно смотреть на ваш код, потому что слишком много кода, которое не имеет отношения к проблеме. –

+1

Класс 'Question' должен быть написан агностиком для любой структуры данных. Что делать, если вы хотите сохранить некоторые вопросы в стеке, некоторые на карте? Вместо этого используйте 'std :: list '. Больше не нужно 'нового'. –

ответ

0

Он вставляет новый узел в связанном списке. Нужно ли мне удалить указатель newQuestion после его появления в списке?

Да. Какой бы ресурс вы не выделили new/new[] вы must удалите его delete/delete[]. В противном случае у вас будет утечка памяти.

Не может это испортить мой список?

delete/delete[] вызывает деструктор своего операнда, если он имеет тип класса. Если ваш класс Question освобождает память, внутренне динамически распределяющую его деструктор, то вы не получите утечки памяти.

Но вам не обязательно динамически выделять класс Question. Просто объявить его как автоматические переменный:

Question newQuestion(text, mark, answers, numAnswers, &this->operator[](qNum-1)); 

Также обратите внимание, что комментарии, которые указуют альтернативы, что вы пытаетесь сделать.

+0

Я обеспокоен тем, что делает конструктор вопроса с переданным им указателем. –

+0

@NeilKirk Действительно, это выглядит довольно странно. – 0x499602D2

Смежные вопросы