2010-07-22 4 views
0

J'ai une grille d'appel de classe. La classe contient deux tableaux 2d char pour stocker une grille ... La classe a deux fonctions pour créer la mémoire pour la grille et libérer la mémoire pour la grille.Double coruption libre

Grid.h

private: 
char **gridOne; 
char **gridTwo; 

Grid.cpp

void Grid::allocateGridMem() 
{ 
    _gridOne = new char*[gridRowCount()]; 
    _gridTwo = new char*[gridRowCount()]; 

    for(int i =0; i < gridColumnCount(); ++i){ 
     *(_gridOne + i) = new char[gridColumnCount()]; 
     *(_gridTwo + i) = new char[gridColumnCount()]; 
    } 
} 

void Grid::dealocateGridMem() 
{ 
    if(_gridOne != 0) 
    { 
     for(int i =0; i < gridRowCount(); ++i){ 
     delete [] *(_gridOne + i); 
     } 
     delete [] _gridOne; 
     _gridOne = 0; 
    } 

    if(_gridTwo != 0) 
    { 
     for(int i =0; i < gridRowCount(); i++){ 
     delete [] *(_gridTwo + i); 
     } 
     delete [] _gridTwo; 
     _gridTwo = 0; 
    } 
} 

Le problème se produit dans la désaffectation de la mémoire que je reçois l'erreur suivante.

*** glibc detected *** ./a.out: double free or corruption (out): 0x088c9318 *** 
    ======= Backtrace: ========= 
    /lib/tls/i686/cmov/libc.so.6(+0x6b591)[0xb756c591] 
    /lib/tls/i686/cmov/libc.so.6(+0x6cde8)[0xb756dde8] 
    /lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0xb7570ecd] 
    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0xb775c741] 
    /usr/lib/libstdc++.so.6(_ZdaPv+0x1d)[0xb775c79d] 
    ./a.out[0x804a7b9] 
    ./a.out[0x8049cb6] 
    ./a.out[0x804b8f3] 
    ./a.out[0x804c06a] 
    ./a.out[0x804b71d] 
    ./a.out[0x80498eb] 
    /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb7517bd6] 
    ./a.out[0x8049521] 
    ======= Memory map: ======== 
    08048000-0804f000 r-xp 00000000 08:02 920728  /home/a.out 
    0804f000-08050000 r--p 00006000 08:02 920728  /home/a.out 
    08050000-08051000 rw-p 00007000 08:02 920728  /home/a.out 
    088c7000-088e8000 rw-p 00000000 00:00 0   [heap] 
    b7300000-b00 rw-p 00000000 00:00 0 
    b00-b7400000 ---p 00000000 00:00 0 
    b7500000-b7501000 rw-p 00000000 00:00 0 
    b7501000-b7654000 r-xp 00000000 08:02 19796293 /lib/tls/i686/cmov/libc-2.11.1.so 
    b7654000-b7655000 ---p 00153000 08:02 19796293 /lib/tls/i686/cmov/libc-2.11.1.so 
    b7655000-b7657000 r--p 00153000 08:02 19796293 /lib/tls/i686/cmov/libc-2.11.1.so 
    b7657000-b7658000 rw-p 00155000 08:02 19796293 /lib/tls/i686/cmov/libc-2.11.1.so 
    b7658000-b765b000 rw-p 00000000 00:00 0 
    b765b000-b7678000 r-xp 00000000 08:02 19791955 /lib/libgcc_s.so.1 
    b7678000-b7679000 r--p 0001c000 08:02 19791955 /lib/libgcc_s.so.1 
    b7679000-b767a000 rw-p 0001d000 08:02 19791955 /lib/libgcc_s.so.1 
    b767a000-b767b000 rw-p 00000000 00:00 0 
    b767b000-b769f000 r-xp 00000000 08:02 19796301 /lib/tls/i686/cmov/libm-2.11.1.so 
    b769f000-b76a0000 r--p 00023000 08:02 19796301 /lib/tls/i686/cmov/libm-2.11.1.so 
    b76a0000-b76a1000 rw-p 00024000 08:02 19796301 /lib/tls/i686/cmov/libm-2.11.1.so 
    b76a1000-b778a000 r-xp 00000000 08:02 28708531 /usr/lib/libstdc++.so.6.0.13 
    b778a000-b778b000 ---p 000e9000 08:02 28708531 /usr/lib/libstdc++.so.6.0.13 
    b778b000-b778f000 r--p 000e9000 08:02 28708531 /usr/lib/libstdc++.so.6.0.13 
    b778f000-b7790000 rw-p 000ed000 08:02 28708531 /usr/lib/libstdc++.so.6.0.13 
    b7790000-b7797000 rw-p 00000000 00:00 0 
    b77a5000-b77a8000 rw-p 00000000 00:00 0 
    b77a8000-b77a9000 r-xp 00000000 00:00 0   [vdso] 
    b77a9000-b77c4000 r-xp 00000000 08:02 19791897 /lib/ld-2.11.1.so 
    b77c4000-b77c5000 r--p 0001a000 08:02 19791897 /lib/ld-2.11.1.so 
    b77c5000-b77c6000 rw-p 0001b000 08:02 19791897 /lib/ld-2.11.1.so 
    bf83a000 

-bf84f000 rw-p 00000000 00:00 0   [stack] 
Aborted 

J'ai vérifié tous mes pointeurs qu'ils ne sont pas modifiés à quelque chose d'autre dans l'exécution et que chaque vérification et d'équilibre, on peut penser est le rite qui se passe. Je me suis arraché les cheveux depuis quelques heures et toujours rien. Je l'utilise avec gcc sur le système Ubuntu 10.

Doit également noter que j'ai changé de nom etc pour les besoins de ce poste et ont seulement inclus le code que je pense être utile.

EDIT:

Correction du problème de syntaxe mais le code d'origine a ce que je viens dactylographié sur rapidement et n'a pas lu la preuve.

Toute aide est grandement appréciée et vaut une étoile d'or dans mon livre. Je suis très un utilisateur avancé de gdb et ai utilisé ceci avec ce problème mais ma pensée que c'est un problème peut-être dans la bibliothèque externe. Je ne peux pas voir de problèmes avec la mémoire et comment elle est limitée en espérant que quelqu'un a vu quelque chose comme ça. Pour toutes les raisons, ce code est correct.

+0

Obtenez-vous un numéro de ligne et quelle serait la ligne équivalente dans votre code? – ChrisF

+1

Je vous suggère de vous renseigner sur valgrind et gdb. – Scharron

+1

Etes-vous en train de faire une copie de cet objet, mais n'avez pas de constructeur de copie qui copie \ _gridOne/\ _ gridTwo? – nos

Répondre

0

sudo apt-get install valgrind, exécutez valgrind myprogram et 99% des bogues d'allocation de mémoire deviennent évidents.

Au moins un des problèmes est que vous affectez la ligne (doit être _gridOne[i]) au-dessus du pointeur de tableau. Compiler avec -Werror -Wall -W et de nombreuses erreurs comme celle-ci deviendront évidentes au moment de la compilation.

1

Probablement il devrait être _gridOne[i] au lieu de _gridOne à l'intérieur de la boucle de allocateGridMem. Mais s'il vous plaît, évitez autant que possible de telles opérations de bas niveau et utilisez plutôt un composant de haut niveau comme boost::numeric::ublas::matrix.

+0

Certainement devrait être '_gridOne [i]' et '_gridTwo [i]' dans 'allocateGridMem', oui. – schnaader

3

changement

for(int i =0; i < gridColumnCount(); ++i){ 
    _gridOne = new char[gridColumnCount()]; 
    _gridTwo = new char[gridColumnCount()]; 
} 

à

for(int i =0; i < gridRowCount(); ++i){ 
    _gridOne[i] = new char[gridColumnCount()]; 
    _gridTwo[i] = new char[gridColumnCount()]; 
} 

Par ailleurs, ne pas faire

*(array + i) 

mais

array[i] 
1

Est-ce que Grid classe de la vôtre ont un constructeur de copie et un opérateur d'affectation ? Sinon, si vous copiez de tels objets, cette erreur serait ce qui se passe.

Je vous suggère cesser de faire la gestion des ressources manuelle et faire Grid une mince enveloppe en deux dimensions autour d'un std::vector<char> qui gère la mémoire.

+0

Il semble que quelqu'un a traversé et abattu toutes les réponses. Je suppose qu'il n'y a aucune raison que quelqu'un voudrait publier? – sbi

0

Utilisez la STL et vecteurs:

class Grid 
{ 
    std::vector<std::vector<char> > grid1; 
    std::vector<std::vector<char> > grid2; 

    public: 
     Grid(int col,int row) 
      : grid1(col, std::vector<char>(row)) 
      , grid2(col, std::vector<char>(row)) 
     {} 
}; 

Tout est fait.

Si vous voulez avoir envie de regarder boost Matrix.