2014-11-09 76 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; 
} 

.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)'返回的任何内容中。原始对象从不再使用,特别是永远不会被释放。 – 2014-11-09 04:05:23

+1

使用'std :: string'和'std :: vector',内存泄漏将神奇地消失。我没有仔细查看你的代码,因为代码太多与问题无关。 – 2014-11-09 04:05:28

+1

“问题”类应该与任何数据结构无关。如果你想在堆栈中存储一些问题,一些在地图中?而是使用'std :: list '。没有'新'需要更多。 – 2014-11-09 04:07:04

回答

0

它插入新节点进入一个链表。它在列表中后是否需要删除newQuestion指针?

是的。无论您分配的资源是new/new[],您需要必须delete/delete[]将其删除。否则,你会有内存泄漏。

这不会搞乱我的名单吗?

delete/delete[]如果它是类类型,则调用其操作数的析构函数。如果Question类解除分配它在内部动态分配的内存使用它的析构函数,那么你不会得到内存泄漏。

但是你不应该动态分配一个Question类。只需将它声明为自动变量:

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

还要注意,那点破替代你想要做什么评论。

+0

我很关心什么问题构造函数用它传递的指针做什么。 – 2014-11-09 04:09:42

+0

@NeilKirk确实,这看起来很奇怪。 – 0x499602D2 2014-11-09 04:10:49