Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

Sujet : Pb:fuite memoire en language c [ Divers / Général ] (PADYVEN)

mercredi 23 janvier 2008 à 09:35:07 | Pb:fuite memoire en language c

PADYVEN

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");
    }
}

//*******************************
//Structures
//*******************************

//Structure noeud
typedef struct Node Node;   //taille 12 octets
struct Node
{
    Node *Prev;
    Node *Next;
    unsigned long int *Data;
};

//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;

    printf("Liste cree avec %ld element\n",liste->NbElements);
    PP=liste->First;
    for (toto=0;toto<liste->NbElements;toto++)
    {
        printf("Element %d (valeur %ld) Adresse:%p\n\tAdresse prec:%p \n\tAdresse next:%p\n",toto,PP->Data,PP,PP->Prev,PP->Next);
        printf("\n");
        PP=PP->Next;
    }
    printf ("\n");
}




mercredi 23 janvier 2008 à 18:41:47 | Re : Pb:fuite memoire en language c

juju12

Dans ClearListID :
free(*P_ListD) au lieu de  free (P_ListD);
à moins que c'était une erreur de copie?

Dans InsertListID :
 P_NoeudTemp->Next=NULL; au lieu de  P_NoeudTemp->Next=P_NoeudRecherche->Next;


sinon, comment sais-tu que tu as une fuite mémoire?

mercredi 23 janvier 2008 à 20:27:08 | Re : Pb:fuite memoire en language c

nickydaquick

Membre Club

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 :

if((*P_ListD)->First)
{
    while((*P_ListD)->First->Next)
    {
       (*P_ListD)->First->Prev = (*P_ListD)->First->Next;
      (*P_ListD)->First->Next = (*P_ListD)->First->Prev->Next;
       free( (*P_ListD)->First->Prev);
    }
    free((*P_ListD)->First);
}

je suis heureux de faire partie d'une grande famille ...!

mercredi 23 janvier 2008 à 20:30:49 | Re : Pb:fuite memoire en language c

nickydaquick

Membre Club

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 ...!

jeudi 24 janvier 2008 à 08:54:52 | Re : Pb:fuite memoire en language c

PADYVEN

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

donc c'est toujours pas parfait



jeudi 24 janvier 2008 à 16:54:59 | Re : Pb:fuite memoire en language c

Spiffou

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.

bon courage


vendredi 25 janvier 2008 à 01:49:08 | Re : Pb:fuite memoire en language c

PADYVEN

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?

sinon je remetrait la liste a jour prochainement.

merci


vendredi 25 janvier 2008 à 09:22:02 | Re : Pb:fuite memoire en language c

nickydaquick

Membre Club

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 ...!

vendredi 25 janvier 2008 à 10:43:37 | Re : Pb:fuite memoire en language c

PADYVEN

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

vendredi 25 janvier 2008 à 18:00:52 | Re : Pb:fuite memoire en language c

nickydaquick

Membre Club

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

//*******************************
//Structures
//*******************************

//Structure noeud
typedef struct Node
{
    Node *Prev;
    Node *Next;
    unsigned long Data;
}Node, *PNode;

//Structure liste
typedef struct DList
{
    Node *Root;     //adresse du premier noeud
    unsigned long Size;   //Nombre d'elements
}DList,*PDList;

//*******************************
//Signature des fonctions
//*******************************
DList *CreateDList();
const char InsertInDList (DList*, const unsigned long);
void FreeDList (DList** );
void printDList(DList*);

//*******************************
//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;

    if(!liste)return;
   
    printf("Liste cree avec %ld element\n",liste->Size);
    PP=liste->First;
    while(PP)
    {
    printf("Element %d (valeur %ld) Adresse:%p\n\tAdresse prec:%p \n\tAdresse next:%p\n\n",(toto++),PP->Data,PP,PP->Prev,PP->Next);
        PP=PP->Next;
    }
    printf ("\n");
}

J'espere avoir aide, salut
je suis heureux de faire partie d'une grande famille ...!


1 2

Cette discussion est classé dans : liste, printf, node, next, listd


Répondre à ce message

Sujets en rapport avec ce message

Passage par adresse d'un tableau de structures. [ par alekine ] Bonjour, j'ai un problème pour passer par adresse un tableau de structures. Voilà mon code:#include #define L_MAX 2struct point //la structure d'un p liste chainée [ par skulls94 ] bonjour, je dois faire un  programme qui lit un fichier mot à mot et qui les stocke dans une liste chainée seulement si ils ne sont pas deja present.v Problem de 'left operand must be a lvalue" [ par Orezza ] Voila je vous mets le code qui est un code trouver sur ce site mais que j'ai modifié. je ne comprends pas les erreurs de compilations pourriez-vous ra demande d'aide pour un carnt d'adresses avec liste chaînée [ par titoune85 ] bonsoir à tous!je vous demande un peu de temps et beaucoup d'aide pour ce pg qui consiste a creer un carnet d'adresse classé par ordre alphabetique. J erreur dans la fonction d'impression [ par dark_cross ] voici j'ai une erreur dans ma fonction d'impression si quelqu'un peux m'expliquer, je serais tres ravie.#include #include //speciale dedicasse Etienne Thread au bout du gouffre!!!!!!!!!!!! [ par LENOX8 ] Salut tout le monde, Merci pour toute les infos que vous m' avez donne, mais etant encore debutant je vois pas trop comment implantes les threads ains Liste chainée [ par mayapour ] Bonjour, Je souhaite faire une liste chainée d'utilisateurs et pouvoir mettre à blanc, ajouter, supprimer, lister et trier cette liste. En faite quand aide petit prog c [ par mayapour ] Bonjour, Débutant en C, je souhaiterai savoir comment changer ce programme initiale (liste chainée) qui demande à l'utilisateur de choisir les optio [c] plantage du program,base 2 donné, surmen un pb de struct [ par Diony ] jvous explique mon probleme . ce programme est une base de données de recettes . et il plante a la fonction inserer_recette_fin_liste (vers le milieu Windows Form Liste dynamique globale [ par Rodrigo62 ] -- Bonjour tout le monde,Je suis en train de réaliser une application avec une Windows Form. Le but est de gérer une liste de pièces.Pour cela, j'ai r


Nos sponsors

Sondage...

CalendriCode

Juillet 2009
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
2728293031  

Consulter la suite du CalendriCode

Téléchargements

Logiciels à télécharger sur le même thème :

Comparez les prix Nouvelle version

Photothèque Nouveau !



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,359 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.