PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : valgrind meldet 3 Fehler -- nur wo sind sie



ContainerDriver
08-04-2004, 14:29
Hallo,
ich schreib gerade das Menü-System für mein Programm neu, und da ich diesmal nicht wieder irgendwelche memory leaks habe will, kontrolliere ich jede Funktion gleich mit valgrind. Dummerweise zeigt mir dieses 3 Fehler an, nämlich:


==7115== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
==7115==
==7115== 1 errors in context 1 of 3:
==7115== Invalid read of size 4
==7115== at 0x8048B9E: Menu::~Menu() (Menu.cpp:89)
==7115== by 0x8049140: main (Menu.cpp:148)
==7115== by 0x40365D16: __libc_start_main (in /lib/i686/libc.so.6)
==7115== by 0x8048860: ??? (start.S:102)
==7115== Address 0x414061E0 is 28 bytes inside a block of size 36 free'd
==7115== at 0x4002D08B: __builtin_delete (in /usr/lib/valgrind/vgskin_memcheck.so)
==7115== by 0x4002D0A9: operator delete(void*) (in /usr/lib/valgrind/vgskin_memcheck.so)
==7115== by 0x8048B91: Menu::~Menu() (Menu.cpp:92)
==7115== by 0x8049140: main (Menu.cpp:148)
==7115==
==7115== 1 errors in context 2 of 3:
==7115== Invalid read of size 4
==7115== at 0x8048B9E: Menu::~Menu() (Menu.cpp:89)
==7115== by 0x8049118: main (Menu.cpp:147)
==7115== by 0x40365D16: __libc_start_main (in /lib/i686/libc.so.6)
==7115== by 0x8048860: ??? (start.S:102)
==7115== Address 0x41406114 is 28 bytes inside a block of size 36 free'd
==7115== at 0x4002D08B: __builtin_delete (in /usr/lib/valgrind/vgskin_memcheck.so)
==7115== by 0x4002D0A9: operator delete(void*) (in /usr/lib/valgrind/vgskin_memcheck.so)
==7115== by 0x8048B91: Menu::~Menu() (Menu.cpp:92)
==7115== by 0x8049118: main (Menu.cpp:147)
==7115==
==7115== 1 errors in context 3 of 3:
==7115== Invalid read of size 4
==7115== at 0x8048B9E: Menu::~Menu() (Menu.cpp:89)
==7115== by 0x80490F0: main (Menu.cpp:146)
==7115== by 0x40365D16: __libc_start_main (in /lib/i686/libc.so.6)
==7115== by 0x8048860: ??? (start.S:102)
==7115== Address 0x41406080 is 28 bytes inside a block of size 36 free'd
==7115== at 0x4002D08B: __builtin_delete (in /usr/lib/valgrind/vgskin_memcheck.so)
==7115== by 0x4002D0A9: operator delete(void*) (in /usr/lib/valgrind/vgskin_memcheck.so)
==7115== by 0x8048B91: Menu::~Menu() (Menu.cpp:92)
==7115== by 0x80490F0: main (Menu.cpp:146)
==7115== IN SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
. valgrind habe ich so gestartet: valgrind --show-reachable=yes --leak-check=yes -v ./debug2. Ich weiß nicht, wie man die Fehler beheben kann und außerdem was sie bedeuten.
Hier ist auch noch mein toller Code (orginal, sonst passen die Zeilenangaben nicht mehr):


//
// C++ Implementation: Menu
//
// Description: simple menu-system, used by tlt(); 3
//
//
// Author: Florian Hanisch <florianhanisch@linuxmail.org>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include <iostream>

using namespace std;
//#include "menu.h"
//#include "../logsys/logsys.h"


struct menu
{
int item_id; //Item-number
char *item; //Item of the menu
char *abbr; //Abbrivation of the item
void *calling;
struct menu *sub; //Pointers to the sub-menus, this produces a tree (see below)
char *translation; //Translation of the item
bool translated;

struct menu*next;
struct menu*prev;
};

class Menu
{
private:
struct menu*start;
struct menu*cur;
struct menu*read;

char*name;

void delete_menu(struct menu *del);
void init_menu(void);
public:
Menu();
Menu(char*);
void setName(const char*);
const char*getName();
~Menu();
/*addItem(); //adds a menu item
addItems(); //wrapper for while(){addItem();}
delItem(); //deletes a menu item
delItems(); //wrapper for while(){delItem();}
setSubMenu(); //sets a sub menu
setCalling(); //sets the func-calling
translateMenu(); //translates the menu [only used, if pointer to a translator is available]
translatePrompt(); //translates the menu-prompt
show(); //shows a menu
choose(); //pompts for user input*/
};

void Menu::delete_menu(struct menu*del)
{
delete[]del->item;
delete[]del->abbr;
delete[]del->translation;
cout << ":::" << flush;
}

void Menu::init_menu()
{
start=new struct menu;
cur=start;
start->item_id=0;
start->item=NULL;
start->abbr=NULL;
start->calling=NULL;
start->sub=NULL;
start->translation=NULL;
start->next=NULL;
start->prev=NULL;

name=NULL;
}

Menu::~Menu()
{
cout << "Starting to delete menu \"" << getName() << "\"..." << flush;
for(read=start;read!=NULL;read=read->next)
{
delete_menu(read);
delete read;
}

delete[]name;
cout << "FINISHED!" << endl << flush;
}

Menu::Menu()
{
cout << "Menu created...";
init_menu();
cout << "FINISHED" << endl;
}

Menu::Menu(char*name_tmp)
{
cout << "Menu created...";
init_menu();
cout << "FINISHED" << endl;
setName(name_tmp);
}

void Menu::setName(const char *name_tmp)
{
delete[]name;
name=new char[strlen(name_tmp)+1];
strcpy(name,name_tmp);

cout << "name \"" << getName() << "\" set" << endl;
}

const char*Menu::getName()
{
return (name==NULL)?"":name;
}

int main (void)
{
Menu *debug_0=new Menu();
Menu *debug_1=new Menu("debug");
Menu *debug_2=new Menu();

cout << "->" << debug_1->getName() << endl;

debug_0->setName("debug_0");
debug_1->setName("debug_1");
debug_2->setName("debug_2");

cout << "->" << debug_0->getName() << endl;
cout << "->" << debug_1->getName() << endl;
cout << "->" << debug_2->getName() << endl;

delete debug_0;
delete debug_1;
delete debug_2;

return 0;
}
.

Schon mal danke fürs lesen & ich hoffe mir kann jemand helfen!

MfG

Florian

wraith
08-04-2004, 15:01
Schau dir deinen Destruktor an:


for(read=start;read!=NULL;read=read->next)
{
delete_menu(read);
delete read; //Jede Zugriff über read ist jetzt ungültig
}

Und was passiert dann am Ende der for, dann wird read = read->next aufgerufen.

ContainerDriver
08-04-2004, 16:09
Arg. Das ist natürlich unschön.
So ist es besser:


for(read=start;read!=NULL;read=start)
{
delete_menu(read);
start=read->next;
delete read;
}

. Vielen Dank wraith!

MfG

Florian