Я довольно новичок в 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;
}
Любые предложения, чтобы избавиться от этой ошибки?
Посмотрите на линии, на которые указывает valgrind. '0x401B1F: IntList :: headInsert (int) (IntList.cpp: 47)' и '0x401BEA: IntList :: endInsert (int) (IntList.cpp: 61)'. Начните трассировку с этих методов, чтобы узнать, правильно ли вы удалили каждый выделенный объект. – smac89
Urgh, для одноэлементного списка, деструктор вызывает удаление 3 раза на том же узле ... Попробуйте вручную перейти через свой код для небольших примеров и вы заметите подозрительные вещи. –
На самом деле, это сложно сказать, не видя точки ввода программы или, по крайней мере, конструкторы для 'IntNode'. – Predelnik