Почему моя функция создает утечку памяти? (C ++)

0

У меня есть строка кода в нижеприведенной программе, которая создает утечку памяти, и я не уверен, почему это так...

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

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

h файл

  #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 комментарий
Теги:

1 ответ

0

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

Да. Независимо от того, какой ресурс вы выделите new/new[] вы должны удалить его с помощью delete/delete[]. В противном случае у вас будет утечка памяти.

Разве это не испортит мой список?

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

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

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

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

  • 0
    Я обеспокоен тем, что конструктор Вопрос делает с указателем, он передается.
  • 0
    @NeilKirk Действительно, это выглядит довольно странно.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню