2014-02-05 4 views
0

Я довольно новичок в C++ и мне никогда не приходилось много думать о управлении памятью. Теперь я создаю связанный список, и все работает так, как предполагается, пока я не попытаюсь проверить мой код. я получаю сообщение «Правильный ответ с ошибками» и ошибки:Ошибка памяти связанного списка C++

==23453== Memcheck, a memory error detector 
==23453== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. 
==23453== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info 
==23453== Command: ./a.out 
==23453== Parent PID: 23452 
==23453== 
==23453== 
==23453== HEAP SUMMARY: 
==23453==  in use at exit: 32 bytes in 2 blocks 
==23453== total heap usage: 27 allocs, 25 frees, 488 bytes allocated 
==23453== 
==23453== 16 bytes in 1 blocks are definitely lost in loss record 1 of 2 
==23453== at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298) 
==23453== by 0x401BEA: IntList::endInsert(int) (IntList.cpp:61) 
==23453== by 0x400D77: main (main.cpp:61) 
==23453== 
==23453== 16 bytes in 1 blocks are definitely lost in loss record 2 of 2 
==23453== at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298) 
==23453== by 0x401B1F: IntList::headInsert(int) (IntList.cpp:47) 
==23453== by 0x40111D: main (main.cpp:118) 
==23453== 
==23453== LEAK SUMMARY: 
==23453== definitely lost: 32 bytes in 2 blocks 
==23453== indirectly lost: 0 bytes in 0 blocks 
==23453==  possibly lost: 0 bytes in 0 blocks 
==23453== still reachable: 0 bytes in 0 blocks 
==23453==   suppressed: 0 bytes in 0 blocks 
==23453== 
==23453== For counts of detected and suppressed errors, rerun with: -v 
==23453== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 6 from 6) 

Вот мой код:

#include<iostream> 
#include "IntList.h" 
#include "IntNode.h" 

IntList::IntList() 
{ 
    // Constructor: creates an empty list 
    head = NULL; 
} 

IntList::~IntList() 
{ 
    // Destructor 
    removeAll(); 
    delete head; 
} 

int IntList::length() 
{ 
    // Returns the length of the list 
    NodePtr temp = head; 
    int count = 0; 

    while (temp != NULL) 
    { 
     temp = temp->getLink(); 
     count++; 
    } 
    return count; 
} 

void IntList::headInsert(int the_number) 
{ 
    // Inserts a node with value the_number at the head of the list 
    if (head == NULL) 
    { 
     head = new IntNode(the_number, NULL); 
    } 
    else 
    { 
     NodePtr newNode = new IntNode(the_number, head); 
     head = newNode; 
    } 
} 

void IntList::endInsert(int the_number) 
{ 
    // Inserts a node with value the_number at the end of the list 
    if (head == NULL) 
    { 
     head = new IntNode(the_number, NULL); 
    } 
    else 
    { 
     NodePtr newNode = new IntNode(the_number, NULL); 
     NodePtr temp = head; 

     while (temp->getLink() != NULL) 
     { 
      temp = temp->getLink(); 
     } 
     temp->setLink(newNode); 
    } 
} 

void IntList::remove(int the_number) 
{ 

    if (head == NULL) 
    { 
     return; 
    } 

    //If head is the only Node left and it's to be removed. 
    if (head->getLink() == NULL && head->getData() == the_number) 
    { 
     head = NULL; 
     delete head; 
     return; 
    } 

    // Removes the first instance of a node with value the_number from the list 
    NodePtr temp = head; 
    if (head->getData() == the_number) 
    { 
     head = head->getLink(); 
     delete temp; 
     return; 
    } 

    NodePtr temp2 = head->getLink(); 
    while (temp2 != NULL) 
    { 
     if (temp2->getData() == the_number) 
     { 
      temp->setLink(temp2->getLink()); 
      delete temp2; 
      return; 
     } 
     temp = temp->getLink(); 
     temp2 = temp2->getLink(); 
    } 
} 

    void IntList::removeAll() 
{ 
    if (head == NULL) 
    { 
     return; 
    } 
    // Removes all the nodes in the list 
    NotePtr temp = head; 
    NodePtr temp2; 
    head = NULL; 

    while (temp != NULL) 
    { 
     temp = temp->getLink(); 
     delete temp2; 
     temp2 = temp; 
    } 
    delete head; 
} 

void IntList::reverse() 
{ 
    if (head == NULL) 
    { 
     return; 
    } 
    // Reverses the order of the nodes in the list 
    NodePtr temp = head; 
    NodePtr temp2 = temp->getLink(); 
    NodePtr temp3 = temp2->getLink(); 

    while (temp3 != NULL) 
    { 
     temp2->setLink(temp); 

     temp = temp2; 
     temp2 = temp3; 
     temp3 = temp3->getLink(); 
    } 
    temp2->setLink(temp); 
    head->setLink(NULL); 
    head = temp2; 
} 

ostream& operator <<(ostream& outs, const IntList& lis) 
{ 
    // A friend function for writing the contents of the list to an output stream 
    NodePtr temp = lis.head; 
    if (temp == NULL) 
    { 
     return outs; 
    } 
    for(NodePtr temp2 = temp; temp2->getLink() != NULL; temp2->getLink()) 
    { 
     outs << temp->getData() << " "; 
     temp = temp->getLink(); 
     temp2 = temp; 
    } 
    outs << temp->getData(); 

    return outs; 
} 

Любые предложения, чтобы избавиться от этой ошибки?

+1

Посмотрите на линии, на которые указывает valgrind. '0x401B1F: IntList :: headInsert (int) (IntList.cpp: 47)' и '0x401BEA: IntList :: endInsert (int) (IntList.cpp: 61)'. Начните трассировку с этих методов, чтобы узнать, правильно ли вы удалили каждый выделенный объект. – smac89

+0

Urgh, для одноэлементного списка, деструктор вызывает удаление 3 раза на том же узле ... Попробуйте вручную перейти через свой код для небольших примеров и вы заметите подозрительные вещи. –

+0

На самом деле, это сложно сказать, не видя точки ввода программы или, по крайней мере, конструкторы для 'IntNode'. – Predelnik

ответ

5

Конечно. Давайте посмотрим на код:

head = NULL; 
delete head; 

Вы настраиваете голову в NULL, а затем пытается удалить его. Это не сработает. Сделайте это в другом порядке. :)

+0

Good поймать !!!!! –

+0

большое спасибо, это сработало :) – user2729307

1

Вы удаляете голову дважды в деструкторе - один раз в removeAll, а затем после этого в деструкторе. Valgrind не жаловался на это, так что, возможно, вы вообще не вызывали delete в списке.

P.S О, вы написали head = NULL ;, поэтому это не было прервано. Но после его удаления вы также должны удалить удаляемую голову в деконструкторе.

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