[Résolu] [C++] Problème de delete
Dernière réponse : dans Programmation
Bonjour à tous !
J'ai un petit problème en C++. Et plus particulièrement avec des delete. Quand je les supprime, tout fonctionne ! Quand je les laisse, j'ai une jolie erreur du type :
L'instruction à "0x77f73aed" emploie l'adresse mémoire "0x00000000". La mémoire ne peut pas être "written".
Et, je ne comprends pas vraiment d'où ça vient. Même si ça doit bien avoir une raison. Voici le code associé à la partie problématique :
La méthode GetSquares() retourne un tableau de pointeurs, comme vous aurez pu le remarquer. Tant qu'à OldSquares, c'est un vector.
Si quelqu'un sait d'où vient l'erreur, je suis preneur ! De même si quelqu'un peut m'expliquer un peu plus en détail le new et le delete. En pratique du moins. Car, la version théorique (avec le malloc), j'ai lu, mais sans plus !
Merci beaucoup ! :-P
J'ai un petit problème en C++. Et plus particulièrement avec des delete. Quand je les supprime, tout fonctionne ! Quand je les laisse, j'ai une jolie erreur du type :
L'instruction à "0x77f73aed" emploie l'adresse mémoire "0x00000000". La mémoire ne peut pas être "written".
Et, je ne comprends pas vraiment d'où ça vient. Même si ça doit bien avoir une raison. Voici le code associé à la partie problématique :
extern Block *FocusBlock, *NextBlock;
Square** tmp_Array1 = FocusBlock->GetSquares();
Square** tmp_Array2 = NextBlock ->GetSquares();
delete FocusBlock, NextBlock;
for( char i = 0 ; i<4 ; i++ )
{
delete tmp_Array1[i];
delete tmp_Array2[i];
}
for( int j = 0 ; j<OldSquares.size() ; j++ )
{
delete OldSquares[j];
}
La méthode GetSquares() retourne un tableau de pointeurs, comme vous aurez pu le remarquer. Tant qu'à OldSquares, c'est un vector.
Si quelqu'un sait d'où vient l'erreur, je suis preneur ! De même si quelqu'un peut m'expliquer un peu plus en détail le new et le delete. En pratique du moins. Car, la version théorique (avec le malloc), j'ai lu, mais sans plus !
Merci beaucoup ! :-P
Autres pages sur : resolu probleme delete
Lassé par la pub ? Créez un compte
Citation :
extern Block *FocusBlock, *NextBlock;
Square** tmp_Array1 = FocusBlock->GetSquares();
Square** tmp_Array2 = NextBlock ->GetSquares();
delete FocusBlock, NextBlock;
for( char i = 0 ; i<4 ; i++ )
{
delete tmp_Array1;
delete tmp_Array2;
}
for( int j = 0 ; j<OldSquares.size() ; j++ )
{
delete OldSquares[j];
}
Salut, si il s 'agit de tableaux que tu veux liberer, peut etre devrais-tu essayer "delete []...[.]".
Non, ça ne marche pas beaucoup plus.
D'autres petites précisions cependant... Il semblerait que ce soit pour "deleter" les tableaux que ça bug. J'ai donc explicité la boucle for, et il semblerait que ce soit trois cas bien particuliers qui posent problèmes. Ceux commentés.
Je ne sais pas trop d'où ça vient... Quelques indications quand même sur le remplissage de ce tableau...
Voilà quelques morceaux de code. Je suis désolé d'en avoir écrit autant (c'est un peu illisible, non ?), mais je pense n'avoir écrit que l'essentiel. Si quelqu'un a une idée...
D'autres petites précisions cependant... Il semblerait que ce soit pour "deleter" les tableaux que ça bug. J'ai donc explicité la boucle for, et il semblerait que ce soit trois cas bien particuliers qui posent problèmes. Ceux commentés.
delete tmp_Array1[0];
delete tmp_Array1[1];
//delete tmp_Array1[2];
delete tmp_Array1[3];
delete tmp_Array2[0];
//delete tmp_Array2[1];
//delete tmp_Array2[2];
delete tmp_Array2[3];
Je ne sais pas trop d'où ça vient... Quelques indications quand même sur le remplissage de ce tableau...
Square** tmp_Array1 = FocusBlock->GetSquares();
Square** tmp_Array2 = NextBlock ->GetSquares();
---------------------------------------------------
class Block
{
// D'autres choses
private:
Square *Squares[4];
}
Square** Block::GetSquares(void)
{
return Squares;
}
// Création des blocs
void Block::SetupSquares(int newX, int newY, SDL_Surface *bitmap)
{
x = newX;
y = newY;
for( char i = 0 ; i < 4 ; i++ )
{
// Les delete là fonctionnent.
if( Squares[i] ) delete Squares[i];
}
switch(type)
{
case SQUARE_BLOCK: // Center = Center of square [0]
// [0][1]
// [2][3]
Squares[0] = new Square( x - SQUARE_SIZE/2, y - SQUARE_SIZE/2, type, bitmap );
Squares[1] = new Square( x + SQUARE_SIZE/2, y - SQUARE_SIZE/2, type, bitmap );
Squares[2] = new Square( x - SQUARE_SIZE/2, y + SQUARE_SIZE/2, type, bitmap );
Squares[3] = new Square( x + SQUARE_SIZE/2, y + SQUARE_SIZE/2, type, bitmap );
break;
// Etc... (C'est un Tetris)
}
}
--------------------------------------------
// Constructeur de la classe Square
Square::Square(int x, int y, BlockType type, SDL_Surface *bitmap): x(x), y(y), type(type), bitmap(bitmap){};
----------------------------------------------
FocusBlock = new Block(BLOCK_START_X, BLOCK_START_Y, SQUARE_BLOCK, square);
NextBlock = new Block(BLOCK_START_X, BLOCK_START_Y, T_BLOCK, square);
Voilà quelques morceaux de code. Je suis désolé d'en avoir écrit autant (c'est un peu illisible, non ?), mais je pense n'avoir écrit que l'essentiel. Si quelqu'un a une idée...
malloc() et free() sont à éviter en C++, à cause de l'existence des opérateurs new et delete qui rendent les choses plus sûres. Donc, non, je n'ai pas touché à ça.
Après m'être penché un peu plus en avant sur le code, je me suis aperçu que je n'avais pas besoin de supprimer tous les Square de mes Block, à cause du destructeur :
Cependant, en les supprimant, j'ai toujours le même message d'erreur, dû à la suppression des deux blocks. Je patauge complètement là. Je pense mettre les sources sur le Net, histoire que ce soit plus simple.
Après m'être penché un peu plus en avant sur le code, je me suis aperçu que je n'avais pas besoin de supprimer tous les Square de mes Block, à cause du destructeur :
Block::~Block()
{
for( char i = 0 ; i < 4 ; i++ )
{
if( Squares[i] ) delete Squares[i];
}
}
Cependant, en les supprimant, j'ai toujours le même message d'erreur, dû à la suppression des deux blocks. Je patauge complètement là. Je pense mettre les sources sur le Net, histoire que ce soit plus simple.
extern Block *FocusBlock, *NextBlock;
Square** tmp_Array1 = FocusBlock->GetSquares();
Square** tmp_Array2 = NextBlock ->GetSquares();
delete FocusBlock, NextBlock;
for( char i = 0 ; i<4 ; i++ )
{
delete tmp_Array1[i];
delete tmp_Array2[i];
}
for( int j = 0 ; j<OldSquares.size() ; j++ )
{
delete OldSquares[j];
}
Sinon pour expliquer l'origine du problème:
C'est un problème très classique dans les programmes complexes de double suppression d'un même objet.
ici tu fais un delete sur FocusBlock avant de supprimer son contenu, c'est très dangereux. Si tu veux faire la même chose qui devrait marcher:
extern Block *FocusBlock, *NextBlock;
Square** tmp_Array1 = FocusBlock->GetSquares();
Square** tmp_Array2 = NextBlock ->GetSquares();
for( char i = 0 ; i<4 ; i++ )
{
delete tmp_Array1[i];
tmp_Array1[i] = 0;
delete tmp_Array2[i];
tmp_Array2[i] = 0;
}
for( int j = 0 ; j<OldSquares.size() ; j++ )
{
delete OldSquares[j];
OldSquares[j] = 0;
}
delete FocusBlock, NextBlock;
sinon pour la dernière question c'est pareil car delete [] (avec les crochets) appelle le destructeur de chaque élément du tableau, donc plus besoin d'alourdir le code source avec une boucle inutile ;-)
On aurait donc pour résultat :
- instanciation de la classe sur tmp_Array1 et tmp_Array2.
- On vide les attributs de l'objet instancié.
- destruction de l'objet.
Quel est l'intérêt de vider les données de l'objet instancié puisque le destructeur s'en occupe lors de son invocation ?
C'est pour faire du remplissage-vidage de mémoire pour du temps réel ?
Une fois l'objet instancié, les zones réservées en mémoire sont bien allouées ? et déstructurées lors de la destruction par delete ?
delete s'applique uniquement aux objets instanciés ou aux variables privées de la classe ?
:-?
cho le c++
- instanciation de la classe sur tmp_Array1 et tmp_Array2.
- On vide les attributs de l'objet instancié.
- destruction de l'objet.
Quel est l'intérêt de vider les données de l'objet instancié puisque le destructeur s'en occupe lors de son invocation ?
C'est pour faire du remplissage-vidage de mémoire pour du temps réel ?
Une fois l'objet instancié, les zones réservées en mémoire sont bien allouées ? et déstructurées lors de la destruction par delete ?
delete s'applique uniquement aux objets instanciés ou aux variables privées de la classe ?
:-?
cho le c++
Citation :
Quel est l'intérêt de vider les données de l'objet instancié puisque le destructeur s'en occupe lors de son invocation ?Effectivement, ça n'a aucun intérêt, et je dirai même qu'il ne faut jamais le faire. Il faut toujours passer par les destructeurs. Comme ça on n'oublie pas la destruction des données si un objet se détruit implicitement.
Citation :
Une fois l'objet instancié, les zones réservées en mémoire sont bien allouées ? et déstructurées lors de la destruction par delete ?Par contre, si on fait des new dans les constructeurs, il faut bien penser à faire tous les deletes dans les destructeur.
Citation :
delete s'applique uniquement aux objets instanciés ou aux variables privées de la classe ?
delete détruit l'objet en mémoire et supprime donc implicitement toutes les données qui n'ont pas été créés par un new (des variables membres dans les classes qui ne sont pas des pointeurs mais directement des objets).
Lassé par la pub ? Créez un compte
- Contenus similaires :
Tags :