[C++ .NET] Structure dynamique
Bonjour
J'ai un nouveau problème :-(
Le but de ce programme doit être la gestion d'une structure dynamique de type FIFO (First In First Out).
L'erreur que j'obtient est une exception NULL reference dans la procédure retraitFile à cette ligne
Code:
mazda_tete = *ptra.elemProch;
donc je suppose que ptra.elemProch est NULL et donc que ma procédure ajoutFile n'est pas bonne mais je ne vois pas ou (ca fait 1 semaine que je bloque la dessus).
Form1. CPP
Code:
1 2 3 4 5 6 7
|
struct bloc
{
int nombre;
struct bloc *elemProch;
};
typedef struct bloc file; |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
#include "stdafx.h"
#include "Form1.h"
#include <windows.h>
#undef MessageBox;
using namespace file_tableau;
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
System::Threading::Thread::CurrentThread->ApartmentState = System::Threading::ApartmentState::STA;
Application::Run(new Form1());
return 0;
}
System::Void Form1::Form1_Load(System::Object * sender, System::EventArgs * e)
{
file tete, queue;
ajoutFile(tete, queue, 1);
MessageBox::Show(Convert::ToString(tete.nombre));
ajoutFile(tete, queue, 2);
MessageBox::Show(Convert::ToString(queue.nombre));
ajoutFile(tete, queue, 3);
retraitFile(tete, queue);
MessageBox::Show(Convert::ToString(queue.nombre));
}
void Form1::initFile(file& mazda_tete,file& mazda_queue)
{
mazda_tete.elemProch = NULL;
mazda_queue.elemProch = NULL;
}
bool Form1::fileVide(file mazda_tete)
{
if(!(mazda_tete.elemProch))
{
return true;
}
else
{
//MessageBox::Show("File NON VIDE");
return false;
}
}
void Form1::ajoutFile(file& mazda_tete, file& mazda_queue, int donnee)
{
file* ptra;
ptra = new(file);
ptra->nombre = donnee;
if(fileVide(mazda_tete))
{
mazda_tete = *ptra;
mazda_queue.elemProch = NULL;
}
else
{
mazda_queue.elemProch = ptra;
mazda_queue = *ptra;
}
//MessageBox::Show(Convert::ToString(mazda_tete.nombre));
}
void Form1::retraitFile(file& mazda_tete, file& mazda_queue)
{
file ptra;
ptra = mazda_tete;
mazda_tete = *ptra.elemProch;
delete(&ptra);
} |
Si quelqu'un voit ou ca cloche ... merci d'avance
Re: [C++.NET] Structure dynamique
Citation:
Envoyé par tidou
Le but de ce programme doit être la gestion d'une structure dynamique de type FIFO (First In First Out).
Il y a quelques problèmes avec l'algo :)
J'ai quelques questions en cours de route, parce que c'est pas super clair :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| System::Void Form1::Form1_Load(System::Object * sender, System::EventArgs * e)
{
file tete, queue;
ajoutFile(tete, queue, 1);
MessageBox::Show(Convert::ToString(tete.nombre));
ajoutFile(tete, queue, 2);
MessageBox::Show(Convert::ToString(queue.nombre));
ajoutFile(tete, queue, 3);
retraitFile(tete, queue);
MessageBox::Show(Convert::ToString(queue.nombre));
} |
'queue' c'est censé être quoi ? Le dernier élément de la liste ?
Code:
1 2 3 4 5
| void Form1::initFile(file& mazda_tete,file& mazda_queue)
{
mazda_tete.elemProch = NULL;
mazda_queue.elemProch = NULL;
} |
Cette méthode n'est jamais appelée, et j'ai toujours du mal à voir la relation entre tete et queue.
Code:
1 2 3 4
| void Form1::ajoutFile(file& mazda_tete, file& mazda_queue, int donnee)
{
file* ptra;
ptra = new(file); |
Problème potentiel ici, le pointeur vers elemProch n'est pas initialisé. Et il ne vaut pas null (plus précisément, il vaut 0xcdcdcdcd d'après mon debuggueur :)
Code:
1 2 3 4 5 6
| ptra->nombre = donnee;
if(fileVide(mazda_tete))
{
mazda_tete = *ptra;
mazda_queue.elemProch = NULL; |
Là tu écrases le contenu de tete, avec donc un pointeur vers elemProch. Et je ne vois toujours pas ce que vient faire queue là-dedans :)
Code:
1 2 3 4 5 6
| }
else
{
mazda_queue.elemProch = ptra;
mazda_queue = *ptra;
} |
Là si je suis le principe de fonctionnement hypothétique, tu veux faire pointer le dernier élément de la liste vers celui que tu viens de créer, et ensuite tu veux décaler ta variable queue qui serait censée pointer sur le nouveau dernier élément. J'ai bon ?
Parce que là ce que tu fais, c'est que tu changes le pointeur vers elemProch dans ta variable queue, et ensuite tu écrases le contenu de cette même variable (dont le pointeur vers elemProch) avec le contenu de ptra. Autrement dit tu remets un elemProch invalide, et c'est toujours la même variable queue.
Code:
1 2 3 4 5 6 7
| void Form1::retraitFile(file& mazda_tete, file& mazda_queue)
{
file ptra;
ptra = mazda_tete;
mazda_tete = *ptra.elemProch;
delete(&ptra);
} |
Et donc le problème de ton post (les problèmes ci-dessus vont t'arriver juste après :).
Toujours en suivant le fonctionnement théorique, tu veux récupérer le premier élément, remplacer la tête par le 2è puis supprimer l'ancien premier élément ?
C'est pas ce que tu fais ici.
Tu crées ptra, initialisé avec elemProch à null et valeur à 0. Tu y copies les données de mazda_tete (qui s'était retrouvé avec un elemProch invalide, cf plus haut). Ensuite, tu écrases le contenu de mazda_tete par le contenu de ce qui se trouve à l'autre bout de son elemProch (qui est donc toujours aussi invalide).
Forcément, ça plante.
Citation:
Envoyé par tidou
Si quelqu'un voit ou ca cloche ... merci d'avance
À plusieurs endroits donc :)
Tu as apparemment un problème avec les notions de passage par valeur, par référence et par pointeurs.
Le gros de ton traitement devrait se faire via des pointeurs. Là vu que tu passes des références, les affectations copient le contenu au lieu des éléments de la liste eux-mêmes.
Actuellement par exemple, ta variable queue créée dans Form1_Load est toujours la même. Si elle est censée pointer sur le dernier élément, c'est raté. Tout ce que tu fais avec, c'est y stocker un elemProch invalide et la valeur du dernier élément 'ajouté'. Mais rien n'est ajouté en fait.
Bref, commence par transformer ta structure en classe, et (surtout), transmets-lui les opérations ajout/retrait/init/vide. C'est à elle de les gérer, pas au code qui l'utilise.
Aussi, devoir transmettre un pointeur/une référence au dernier élément de la liste pour chaque opération, c'est pas une bonne idée (mais ça se règle tout seul une fois que tu isoles le traitement dans sa propre classe :)