C++ crash en mémoire avec tableaux

Fermé
dword2add Messages postés 1 Date d'inscription samedi 10 novembre 2007 Statut Membre Dernière intervention 10 novembre 2007 - 10 nov. 2007 à 20:59
mamiemando Messages postés 33367 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 19 novembre 2024 - 11 nov. 2007 à 14:14
Bonjour,

J'ai le programme suivant (imlémentation d'un stack) :

#include <stdlib.h>

#include <iostream>

#include <string>


using namespace std;


int nb = 0; // number of elements
int k = 2; // maximum number of elements

int *table; // point to the main table

// init hte stack
void init()
{
table = new int[2];
k=2;
nb = 0;
}

// take an element
int pop()
{
// if stack is empty
if (nb == 0) {
cout << "stack is empty" << endl;
return -1;
}
nb--;
return table[nb];
}

// write an element in the stack
void push(int element)
{
// if the table can't accept the new element
if ((nb + 1) > k) {
int *p; // new pointer for the new table
k = 2 * k;
p = new int[k];

// copy the content to the new table
int i;
for (i = 0; i < nb; i++) {
p[i] = table[i];
}
// delete the old table
delete[] table;
// change the pointer
table = p;
}
// write the element
table[nb] = element;
nb++;
}

// return the size of the stack
int size()
{
return nb;
}

// kill the table in memory
void clear()
{
delete[] table;
nb=0;
}




//Dieses Funktion implementiert eine Testumgebung für den Stack

int test()
{
cout << "The program has been startet without any arguments." << endl;
cout << "The program enters the stack test mode:" << endl;
cout << "Enter one of the commands: push, pop, end" << endl;

string command;


do {
cin >> command;
if (command == "pop") {
cout << pop() << endl;
} else if (command == "push") {
cout << "element?";
int elementToPush;
cin >> elementToPush;
push(elementToPush);
} else if (command == "end") {
clear();
} else {
cout << "command not recognised" << endl;
};
}
while (command != "end");
return 0;
}


int main(int argc, char *argv[])
{
init();
test();
clear();
return 0;
}

J'obtiens le résultat suivant (qui est correct) masi avec un message d'erreur :

The program has been startet without any arguments.
The program enters the stack test mode:
Enter one of the commands: push, pop, end
push
element?4
push
element?1
pop
1
push
element?5
push
element?9
pop
9
pop
5
pop
4
pop
stack is empty
-1
end

*** glibc detected *** ./array: double free or corruption (fasttop): 0x0804b008 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7d2dd65]
/lib/tls/i686/cmov/libc.so.6(cfree+0x90)[0xb7d31800]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb7ef6d81]
/usr/lib/libstdc++.so.6(_ZdaPv+0x1d)[0xb7ef6ddd]
./array(__gxx_personality_v0+0x1ae)[0x8048a32]
./array[0x8048cf4]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe0)[0xb7cda050]
./array(__gxx_personality_v0+0x4d)[0x80488d1]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 08:03 1126215 /home/tguillod/eth/info/ubung/u6/array
0804a000-0804b000 rw-p 00001000 08:03 1126215 /home/tguillod/eth/info/ubung/u6/array
0804b000-0806c000 rw-p 0804b000 00:00 0 [heap]
b7b00000-b7b21000 rw-p b7b00000 00:00 0
b7b21000-b7c00000 ---p b7b21000 00:00 0
b7cc3000-b7cc4000 rw-p b7cc3000 00:00 0
b7cc4000-b7e08000 r-xp 00000000 08:03 476707 /lib/tls/i686/cmov/libc-2.6.1.so
b7e08000-b7e09000 r--p 00143000 08:03 476707 /lib/tls/i686/cmov/libc-2.6.1.so
b7e09000-b7e0b000 rw-p 00144000 08:03 476707 /lib/tls/i686/cmov/libc-2.6.1.so
b7e0b000-b7e0e000 rw-p b7e0b000 00:00 0
b7e0e000-b7e18000 r-xp 00000000 08:03 473347 /lib/libgcc_s.so.1
b7e18000-b7e19000 rw-p 0000a000 08:03 473347 /lib/libgcc_s.so.1
b7e19000-b7e1a000 rw-p b7e19000 00:00 0
b7e1a000-b7e3d000 r-xp 00000000 08:03 476715 /lib/tls/i686/cmov/libm-2.6.1.so
b7e3d000-b7e3f000 rw-p 00023000 08:03 476715 /lib/tls/i686/cmov/libm-2.6.1.so
b7e3f000-b7f27000 r-xp 00000000 08:03 230797 /usr/lib/libstdc++.so.6.0.9
b7f27000-b7f2a000 r--p 000e8000 08:03 230797 /usr/lib/libstdc++.so.6.0.9
b7f2a000-b7f2c000 rw-p 000eb000 08:03 230797 /usr/lib/libstdc++.so.6.0.9
b7f2c000-b7f32000 rw-p b7f2c000 00:00 0
b7f47000-b7f4b000 rw-p b7f47000 00:00 0
b7f4b000-b7f65000 r-xp 00000000 08:03 473300 /lib/ld-2.6.1.so
b7f65000-b7f67000 rw-p 00019000 08:03 473300 /lib/ld-2.6.1.so
bfc3c000-bfc52000 rw-p bfc3c000 00:00 0 [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso]
Aborted (core dumped)


C'est un problème de libération de mémoire (fonction clear()). Mais je n'arrive pas le trouver.
Quelqu'un peut il m'aider ?
A voir également:

1 réponse

mamiemando Messages postés 33367 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 19 novembre 2024 7 801
11 nov. 2007 à 14:14
Ce genre d'erreur survient quand tu libères une zone mémoire déjà libérée soit avec un free, soit avec un delete. Pour éviter ce genre de problème il faut vraiment se discipliner dans la gestion de la mémoire :
- un constructeur qui fait un new => le destructeur fait le delete correspondant.
- un new dans un scope (un scope ou horizon en français c'est une paire d'accolade, par exemple une fonction ou une boucle) => le delete correspondant en fin de scope.

De manière générale en C++ on a rarement besoin de faire des new on peut presque toujours s'en sortir avec juste des références et des constructeurs ordinaires. AUtre conseil évite les variables globales !

Bonne chance
1