PADYVEN
Messages postés69Date d'inscriptionlundi 10 février 2003StatutMembreDernière intervention29 août 2012
-
23 janv. 2008 à 09:35
PADYVEN
Messages postés69Date d'inscriptionlundi 10 février 2003StatutMembreDernière intervention29 août 2012
-
28 janv. 2008 à 09:51
Bonjour ,
voila je devellope une liste double pour apprendre le c
rien ne vaut la pratique
j'ai 3 fonctions une pour creer la liste ,une pour inserer un element ,une pour supprimer la liste
le probleme c'est que j'ai une fuite de memoire mais je n'arrive pas a comprendre pourquoi ci-joint le code d'utilisation et les bout de code utilisé pour la liste
les printf sont ceux que j'ai utilisé pour debugger
Ps :merci d'etre tres explicatif parce que la je pense etre pas tres tres bon
MERCI BEAUCOUP
//*******************************
//utilisation
//*******************************
void testlist()
{
int toto=0;
ListeDouble *malist;
system("cls");
printf("creation de la Liste\n");
system("Pause");
malist=CreateListD();
if (malist!=NULL)
{
//test deux methode pour le nombre d'element
printf("Liste cree avec %ld element\n",malist->NbElements);
//insert 10000 elements
printf("Insertion des elements\n");
system("Pause");
for (toto=0;toto<10;toto++)
{
//ajout un element
InsertListD(malist,toto);
}
printlist(malist);
printf("Efface la liste\n");
system("Pause");
ClearListD (&malist);
printf("Fin avant sortie\n");
system("Pause");
}
}
//Structure liste
typedef struct ListeDouble ListeDouble; //taille 16 octets
struct ListeDouble
{
Node *First; //adresse du premier noeud
Node *Last; //adresse du noeud de fin
Node *NoeudTravail; //adresse du noeud de fin
unsigned long int NbElements; //Nombre d'elements
};
//*******************************
//Codes de gestion
//*******************************
/*-------------------------------
Nouvelle liste
Renvoi un pointeur de type liste double
---------------------------------*/
//premier noeud precedant=NULL
//dernier noeud suivant=NULL
ListeDouble *CreateListD (void)
{
ListeDouble *P_ListD = malloc (sizeof (ListeDouble));
if (P_ListD)
{//memoire alloué
//initialisation de la liste
P_ListD->First = NULL;
P_ListD->Last = NULL;
P_ListD->NbElements=0;
}
else
{
fprintf (stderr, "Memoire insufisante\n");
exit (EXIT_FAILURE);
}
return P_ListD;
}
/*-------------------------------
Insert un element
---------------------------------*/
//insert suivant data
void InsertListD (ListeDouble *P_ListD, unsigned long int *Data)
{
if (P_ListD)
{//si pointeur sur liste non nul
//P_NoeudTemp nouveau noeud a insere
Node *P_NoeudTemp = NULL;
P_NoeudTemp = malloc (sizeof (Node));
if (P_NoeudTemp!=NULL)
{
//set les data
P_NoeudTemp->Data = Data;
if (P_ListD->First == NULL)
{//premiere insertion dans la liste
P_ListD->First = P_NoeudTemp;
P_NoeudTemp->Prev = NULL;
P_NoeudTemp->Next = NULL;
}
else
{//recherche le noeud a inserer
//P_NoeudRecherche le noeud pour parcourir la liste setter au debut
Node *P_NoeudRecherche = P_ListD->First;
while(P_NoeudRecherche->Next)
{ //tant que le suivant n'est pas null
P_NoeudRecherche=P_NoeudRecherche->Next;
}
//remplace le noeud suivant
P_NoeudTemp->Prev=P_NoeudRecherche;
P_NoeudTemp->Next=P_NoeudRecherche->Next;
P_NoeudRecherche->Next=P_NoeudTemp;
}
//increment le nombre d'element
P_ListD->NbElements++;
}
else
{
fprintf (stderr, "Memoire insuffisante\n");
exit (EXIT_FAILURE);
}
}
}
/*-------------------------------
Efface la liste double
---------------------------------*/
void ClearListD (ListeDouble ** P_ListD)
{ //efface la liste ** P_ListD car on doit modifier le pointeur de liste envoyé
if (P_ListD!=NULL)
{
//Efface les elements recursivement
node_clear_r((*P_ListD)->First);
//supprime la liste
free (P_ListD);
*P_ListD = NULL;
}
}
/*-------------------------------
Efface les elements recursivement
---------------------------------*/
void node_clear_r (Node *p_node)
{
if (p_node != NULL)
{
node_clear_r (p_node->Next);
printf("Element effacé adresse:%p\n",p_node);
free (p_node);
}
}
/*-------------------------------
Affiche la liste sur la sortie standard
---------------------------------*/
void printlist(ListeDouble *liste)
{
int toto=0;
Node *PP;
nickydaquick
Messages postés416Date d'inscriptionvendredi 31 janvier 2003StatutMembreDernière intervention19 décembre 20133 23 janv. 2008 à 20:27
Salut 2 Erreurs;
1- ta boucle for tu utilises des int que tu passes par VALEUR a la fonction InsertListD qui requiert que le parametre 2 soit passe par ADRESSE, et ce qui est drole ce que tous tes noeuds vont donc pointer a la meme adresse , heureusement que tu ne detruis pas la memoire pointee par le noeud
2-dans la fonction ClearListD tu passes une adresse du pointeur de liste : parfait
l'erreur , il faut verifier aussi que *P_ListD!=NULL,
et lorsque tu liberes la liste : free(*P_ListD);
les fonctions recursives , non pas vraiment :
nickydaquick
Messages postés416Date d'inscriptionvendredi 31 janvier 2003StatutMembreDernière intervention19 décembre 20133 23 janv. 2008 à 20:30
Salut,
dans l'erreur 1 , je voulais dire si tu passais correctement l'argument par ADRESSE tous les pointeurs de la liste aurait la meme adresse comme DATA, mais en le laissant tel quel, le valeur de toto (0,1,2,....) va etre consideree comme l'adresse d'un emplacement memoire ( a priori invalide)==crash lors de l'acces;
je suis heureux de faire partie d'une grande famille ...!
Vous n’avez pas trouvé la réponse que vous recherchez ?
PADYVEN
Messages postés69Date d'inscriptionlundi 10 février 2003StatutMembreDernière intervention29 août 2012 24 janv. 2008 à 08:54
salut,
donc j'ai corriger les erreurs que vous m'avez idinqué, c'est mieux
mais je crois que ca fuit toujours un petit peu
pour tester les fuites j'ai deux methodes
la bourrin:
-des system("Pause"); avant l'insertion et avant le delete et ma boucle d'insertion comporte 10000 elements et je regarde avec le TASK manager de windows
l'util memoire de mon appli
sinon la plus fine
j'utilise les printf du programme pour verifier si avec deux utilisations de TestList j'utilise les memes adresses memoires pour les noeud et pour la liste
donc quand je dis que c'est mieux, je vois avec la deuxieme methode que j'utilise les meme adresse memoires mais pas dans le meme ordre
et avec la deuxieme methode mon appli fait 1208ko en memoire avant l'insertion des elements (10000 elements) 1448ko apres et 1268 apres la suppression
j'aurais donc logiquement une fuite de 40ko
Spiffou
Messages postés100Date d'inscriptionjeudi 1 avril 2004StatutMembreDernière intervention 9 juin 20141 24 janv. 2008 à 16:54
une technique simple pour détecter rapidement une fuite mémoire:
ajoute un tableau de double (car ca prend plus de place en mémoire) dans ta structure node
struct Node
{
Node *Prev;
Node *Next;
unsigned long int *Data;
double buff[20000]; // tu peux encore augmenter la taille du tableau pour que la fuite sois plus voyante
};
de cette façon il y aura une fuite bien visible en cas de non désallocation d'une partie des noeux.
PADYVEN
Messages postés69Date d'inscriptionlundi 10 février 2003StatutMembreDernière intervention29 août 2012 25 janv. 2008 à 01:49
quelqu'un pourrait m'expliquer pourquoi mes elements apres la deuxieme allocation n'utilise pas la place memoire dans le meme ordre
si mon programme ne fais rien d'autre ca devrait etre le cas non?
nickydaquick
Messages postés416Date d'inscriptionvendredi 31 janvier 2003StatutMembreDernière intervention19 décembre 20133 25 janv. 2008 à 09:22
Salut,
veux tu qu'on te donne un exemple de liste doublement chainee en C?
la ca pourra t'aider , tu compareras et voila.
je suis heureux de faire partie d'une grande famille ...!
PADYVEN
Messages postés69Date d'inscriptionlundi 10 février 2003StatutMembreDernière intervention29 août 2012 25 janv. 2008 à 10:43
oui pourquoi pas
merci beaucoup
j'ai deja telechargé beaucoup d'exemples mais avec des noms pas toujours explicite ou pas de commentaires des fois c'est difficille
je vais utiliser cette liste dans un cas tres particulier elle doit etre tres rapide pour l'insertion et ce sera une insertion triee
nickydaquick
Messages postés416Date d'inscriptionvendredi 31 janvier 2003StatutMembreDernière intervention19 décembre 20133 25 janv. 2008 à 18:00
Salut,
bon vite fait en C , ton code retape. J'ai laisse tes commentaires en place, modifie quelque peu le nom des fonctions et procedures. Test it and if possible, enjoy it then
//*******************************
//utilisation
//*******************************
void testlist()
{
unsigned long toto=0;
PDList list;
system("cls");
printf("creation de la Liste\n");
system("Pause");
list=CreateDList();
if(list)
{
//test deux methode pour le nombre d'element
printf("Liste cree avec %ld element\n",list->Size);
//insert 10elements
printf("Insertion des elements\n");
system("Pause");
for(toto=0;toto<10;++toto)
{
//ajout un element
if(!InsertInDList(list,toto))printf("Erreur-Insertion element : %i",toto);
}
printDList(list);
printf("Efface la liste\n");
system("Pause");
ClearDList (&list);
printf("Fin avant sortie\n");
system("Pause");
}
}
/*******************************
//Codes de gestion
//*******************************
/*-------------------------------
Nouvelle liste
Renvoi un pointeur de type liste double
---------------------------------*/
DList *CreateDList()
{
PDList P_ListD = malloc(sizeof (DList));
if (P_ListD)
{//memoire alloué
//initialisation de la liste
P_ListD->Root = 0;
P_ListD->Size = 0;
}
else
fprintf (stderr, "Memoire insufisante\n");
return P_ListD;
}
/*-------------------------------
Insert un element
---------------------------------*/
const char InsertInDList (DList *P_ListD, const unsigned long Data)
{
if (P_ListD)
{//si pointeur sur liste non nul
//P_NoeudTemp nouveau noeud a insere
PNode P_NoeudTemp = malloc (sizeof (Node));
if(!P_NoeudTemp)
{
//set les data
P_NoeudTemp->Data = Data; P_NoeudTemp->Prev P_NoeudTemp->Next 0;
if (!P_ListD->First)
//premiere insertion dans la liste
P_ListD->First = P_NoeudTemp;
else
{//recherche le noeud a inserer
//P_NoeudRecherche le noeud pour parcourir la liste setter au debut
PNode P_NoeudRecherche = P_ListD->First;
while(P_NoeudRecherche->Next)
//tant que le suivant n'est pas null
P_NoeudRecherche=P_NoeudRecherche->Next;
//remplace le noeud suivant
P_NoeudTemp->Prev=P_NoeudRecherche;
P_NoeudRecherche->Next=P_NoeudTemp;
}
//increment le nombre d'element
++P_ListD->Size;
}
else
{
fprintf (stderr, "Memoire insuffisante\n");
return 0;//failure, no item inserted
}
}
return 1;//success , one item inserted
}
/*-------------------------------
Efface la liste double
---------------------------------*/
void ClearDList (DList** P_ListD)
{ //efface la liste ** P_ListD car on doit modifier le pointeur de liste envoyé
if (P_ListD && *P_ListD)
{
//Efface les elements recursivement
while((*P_ListD)->First->Next)
{
(*P_ListD)->First->Prev = (*P_ListD)->First->Next;
(*P_ListD)->First->Next = (*P_ListD)->First->Next->Next;
free((*P_ListD)->First->Prev);
}
free((*P_ListD)->First);
//supprime la liste
free (*P_ListD);
*P_ListD = NULL;
}
}
/*-------------------------------
Affiche la liste sur la sortie standard
---------------------------------*/
void printDList(DList *liste)
{
unsigned long toto=0;
PNode PP;