2012-05-13 12 views
2

addStudent関数とmainMenu関数は、重要な2つです。このリークメモリはありますか?

#include <iostream> 
#include <string> 

using namespace std; 

struct Student 
{ 
    string name; 
    string major; 
    Student *p_next; 
}; 

Student *addStudent(Student *p_students) 
{ 
    Student *p_new_student = new Student; 
    cout << "Student name: \n"; 
    cin >> p_new_student->name; 
    cout << p_new_student->name << "'s major: \n"; 
    cin >> p_new_student->major; 

    Student *p_place_holder = new Student; 
    Student *p_all_students = new Student; 
    p_all_students = p_students; 
    p_place_holder = NULL; 

    if (p_students == NULL) // Adds the first element to the linked list which was initialized to NULL 
    { 
     p_new_student->p_next = p_students; 
     delete p_place_holder; 
     delete p_all_students; 
     return p_new_student; 
    } 

    else // Adds elements beyond the first element to the linked list 
    { 
     while (p_all_students != NULL) 
     { 
     if (p_new_student->name.compare(p_all_students->name) <= 0) 
     { 
      if (p_place_holder == NULL) /* if p_new_student->name is before 
      p_all_students->name and p_all_students is still the first element in the list*/ 
      { 
       p_new_student->p_next = p_all_students; 
       p_all_students = p_new_student; 
       delete p_place_holder; 
       return p_all_students; 
      } 

      else 
      { 
       p_new_student->p_next = p_all_students; 
       p_place_holder->p_next = p_new_student; 
       return p_students; 
      } 

     } 

     else if (p_new_student->name.compare(p_all_students->name) > 0) 
     { 
      p_place_holder = p_all_students; 
      p_all_students = p_all_students->p_next; 
     } 
     } 
    } 
} 

void mainMenu(Student *p_students) 
{ 
    int response = 0; 
    cout << "1. Add Student\n"; 
    cout << "2. View Students\n"; 
    cin >> response; 

    if (response == 1) // calls addStudent 4 times and then mainMenu 
    { 
     p_students = addStudent(p_students); 
     p_students = addStudent(p_students); 
     p_students = addStudent(p_students); 
     p_students = addStudent(p_students); 
     mainMenu(p_students); 
    } 

    else if (response == 2) // lists the students and their majors and then exits 
    { 
     while (p_students != NULL) 
     { 
     cout << p_students->name << '\n'; 
     cout << p_students->major << "\n\n"; 
     p_students = p_students->p_next; 
     } 
    } 

    delete p_students; // hopefully deletes all allocated memory 
} 

int main() 
{ 
    Student *p_students = new Student; 
    p_students = NULL; 

    mainMenu(p_students); 
} 

"delete p_students;"プログラムがメモリをリークしないように、mainMenu関数内のすべての割り当てられたメモリを適切に削除します。どんな助けもありがとう、ありがとう。

+3

これは多くのコードですが、問題を説明する最小のコンパイル可能なコードに減らそうとする必要があります。 – amit

+1

また、_valgrind_のようなユーティリティを使ってプログラムを実行すると、ここに問い合わせることなくメモリがリークするかどうかがわかります! –

+0

@MrLister:漏れを防ぐためにコードを読んで理由を考えるのがずっと良いです。 –

答えて

6

これらの行は、学生のインスタンスを漏れます

Student *p_place_holder = new Student; 
Student *p_all_students = new Student; 
p_all_students = p_students; 
p_place_holder = NULL; 

あなたは、後でインスタンスを削除せずにNULLでポインタを上書きし、p_place_holderに割り当て、生徒を割り当てます。

また、持っている:

古い値でメモリを解放しようとせずに p_students 3回上書きします
p_students = addStudent(p_students); 
p_students = addStudent(p_students); 
p_students = addStudent(p_students); 
p_students = addStudent(p_students); 

大きな問題はdelete p_studentsで終わりますが、Student構造体を調べて、その中のポインタを見つけたり、削除したりするなど、再帰的には望みどおりに行いません。割り当てたメモリのほとんどがすべてリークしています。

私は新しいものと削除するペアを一緒に誤解していると思います。

+0

私は、これは2つを使用して私の最初のプログラムです。 addStudent関数でdeleteを使用すると、リストの最初の項目を指すために使用しているp_students学生が削除されますか?新しい生徒にp_studentsを割り当てて、その関数が呼び出されるたびに古い生徒を削除する必要がありますか? –

+0

また、リンクされたリスト内のStudentのすべてのインスタンスを削除するために、whileループはmainMenuの最後で動作しますか?のようなwhile(p_students!= NULL){//コード}? –

+0

@BlakeMadden:あなたが指し示す価値を放棄するたびに、それを削除する必要があります。これは、ポインタを上書きするときや、ポインタ自体にポインタがある構造体を削除したときなどです。 –

0

メモリリークを防ぐには、強制所有権ポインタを使用する必要があります。たとえば、unique_ptrおよびshared_ptrです。 deleteで漏れを効果的に防ぐことはできません。

+2

「決して」?驚くべきことに、これらのクラスが利用可能になる前にすべてのソフトウェアが書かれています... :) –

+1

私は 'new' /' delete'を排他的に使用しています。私はそれがいくつかの経験を持つことは便利だと思います。問題が発生した場合、Valgrindは非常に効果的なヘルプです。 – TaZ

+0

@NedBatchelder:人々はバグに住んでいました。また、ソフトウェアははるかに小さく、ずっと複雑ではありませんでした。 – Puppy

関連する問題