IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

realloc: mise à jour d'adresse memoire


Sujet :

C

  1. #1
    Membre actif
    Inscrit en
    Juin 2008
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 33
    Par défaut realloc: mise à jour d'adresse memoire
    je veux compter et afficher le nombre de chaque caractère existant dans un fichier texte pour cela j'utilise un tableau de structure (Adr_Tableau_Asci).
    si le caractere déjà existe dans mon tableau alors juste j'incrémente le nombre de caractère siono j'alloue un structure dont je met le caractère
    question: lorsque j'utilise realloc j'obtient une adresse memoire ou bien le meme adresse memoire avec un taille different ??
    voici le code j ai eu des problème lors d'execution
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    	Adr_Tableau_Asci=(struct Noeud*)malloc(sizeof(struct Noeud*));
     
             if (fich==NULL)
     
    	              perror("imp");
     
              else
                      {
    					  do
                              {
                                      Caractere = fgetc(fich); // On lit le caractère
                                      printf("%c", Caractere); // On l'affiche 
                                      Taille++;
                                      Calcul_Occurence_Caractere(Caractere,&Adr_Tableau_Asci,Taille);
                               } while (Caractere!= EOF); // On continue tant que fgetc n'a pas retourné EOF (fin de fichier)
     
    	              }
    	      fclose(fich);
     
     
        getchar();
    	return 0;
    }
    void Calcul_Occurence_Caractere(char Caractere, struct Noeud **Tableau_Asci ,int Taille)
    {
    	int test;
    	struct Noeud * Element_Tableau;
    	struct Noeud **Tableau;
     
     
        test=Recherche_Caractere_TASCI(Caractere,&Tableau_Asci,Taille);
        printf(" donner test %d\n ",test);
     
        if (test==-1)
        {
      		Element_Tableau=malloc(sizeof(struct Noeud));
    		Element_Tableau->lettre=Caractere;
    		Element_Tableau->occurence=1;
    		Tableau_Asci=realloc(Tableau_Asci,Taille+1*sizeof(struct Noeud*));
     
     
        }
        else
         {
            Tableau_Asci[test]->occurence++;	
         }
     
     
    }
    int Recherche_Caractere_TASCI(char Caractere, struct Noeud **Tableau_Asci  ,int Taille )
    {
    	int i;
    	for(i=0;i<Taille;i++)
    	 if(Tableau_Asci[i]->lettre==Caractere)
    	 {
     		return i;
     		break;
     	}
     	return -1;
    }

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    question: lorsque j'utilise realloc j'obtient une adresse memoire ou bien le meme adresse memoire avec un taille different ??
    Ce peut être la même adresse ou une autre. Il est possible que le bloc de données ait été déplacé pour obtenir un bloc mémoire contiguë de la taille demandée. On ne peut pas préjuger qu'on se trouvera dans un cas ou dans l'autre.
    A noter que l'adresse renvoyée peut être NULL, si la mémoire demandée ne peut être allouée et le bloc précédemment alloué le reste dans ce cas. Il faut éviter alors une fuite mémoire et c'est pourquoi, le schéma d'utilisation de realloc() est le suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     p = realloc(q,....);
     if(p != NULL)
     {
         q = p;
         // utilisation du bloc à l'adresse q
     }
     else 
    {  
        // erreur de reallocation et disposition à prendre dans ce cas
        // par exemple :
        // free(q), q=NULL;
    }

  3. #3
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Bonjour,

    Pour le fonctionnement de realloc la man page de realloc donne :
    realloc() renvoie un pointeur sur la mémoire nouvellement allouée, qui est correctement alignée pour n'importe quel type de variable, et qui peut être différent de ptr, ou NULL si la demande échoue.
    La première ligne de ton code posté est : Adr_Tableau_Asci=(struct Noeud*)malloc(sizeof(struct Noeud*));, je pense qu'il y a une erreur et que tu voulais plus écrire Adr_Tableau_Asci=(struct Noeud*)malloc(sizeof(struct Noeud)); ? non ?

  4. #4
    Membre actif
    Inscrit en
    Juin 2008
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 33
    Par défaut
    Citation Envoyé par kwariz Voir le message
    Bonjour,

    Pour le fonctionnement de realloc la man page de realloc donne :


    La première ligne de ton code posté est : Adr_Tableau_Asci=(struct Noeud*)malloc(sizeof(struct Noeud*));, je pense qu'il y a une erreur et que tu voulais plus écrire Adr_Tableau_Asci=(struct Noeud*)malloc(sizeof(struct Noeud)); ? non ?
    non Adr_Tableau_Asci est adresse tableau de pointeur sur structure Noeud
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct Noeud ** Adr_Tableau_Asci;

  5. #5
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par twity Voir le message
    non Adr_Tableau_Asci est adresse tableau de pointeur sur structure Noeud
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    struct Noeud ** Adr_Tableau_Asci;
    Alors tu as un problème de cast ... d'une manière générale il est recommandé de ne pas caster le retour d'un malloc.

  6. #6
    Membre actif
    Inscrit en
    Juin 2008
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 33
    Par défaut
    Citation Envoyé par kwariz Voir le message
    Alors tu as un problème de cast ... d'une manière générale il est recommandé de ne pas caster le retour d'un malloc.
    je pense que mon problème se situe dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void Calcul_Occurence_Caractere(char Caractere, struct Noeud **Tableau_Asci ,int Taille)
    car le programme affiche le premier et 2 carctere de contenu du fichier texte et après se bloque

  7. #7
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par twity Voir le message
    je pense que mon problème se situe dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void Calcul_Occurence_Caractere(char Caractere, struct Noeud **Tableau_Asci ,int Taille)
    car le programme affiche le premier et 2 carctere de contenu du fichier texte et après se bloque
    Oui, c'est clair. Je ne commençais que par la première ligne.
    Tu alloues Element_tableau, tu rallonges Tableau_Asci mais où ajoutes-tu Element_tableau à Tableau_asci ?

    As-tu essayé d'exécuter ton programme pas à pas dans un débuggueur ?

  8. #8
    Membre actif
    Inscrit en
    Juin 2008
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 33
    Par défaut
    Citation Envoyé par kwariz Voir le message
    Oui, c'est clair. Je ne commençais que par la première ligne.
    Tu alloues Element_tableau, tu rallonges Tableau_Asci mais où ajoutes-tu Element_tableau à Tableau_asci ?

    As-tu essayé d'exécuter ton programme pas à pas dans un débuggueur ?
    oui j'oublie de mettre le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tableau_Asci[Taille+1]=Element_Tableau;
    mais le proleme persiste encore

  9. #9
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par twity Voir le message
    oui j'oublie de mettre le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tableau_Asci[Taille+1]=Element_Tableau;
    mais le proleme persiste encore
    Dans le realloc tu a aussi oublié les parenthèses autour de Taille + 1 ?
    Tu as essayé le pas à pas dans un débuggueur ?

  10. #10
    Membre actif
    Inscrit en
    Juin 2008
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 33
    Par défaut
    Citation Envoyé par twity Voir le message
    oui j'oublie de mettre le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tableau_Asci[Taille+1]=Element_Tableau;
    mais le proleme persiste encore
    realloc conserver l'ancien contenu??

  11. #11
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par twity Voir le message
    realloc conserver l'ancien contenu??
    Oui, tant que tu ne demandes pas une taille plus petite.

  12. #12
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par twity Voir le message
    oui j'oublie de mettre le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tableau_Asci[Taille+1]=Element_Tableau;
    mais le proleme persiste encore
    Taille + 1 éléments -> les indices varient de 0 à Taille
    Tu modifies Taille, comment sais-tu au retour de la fonction que Taille a changé ?

  13. #13
    Membre actif
    Inscrit en
    Juin 2008
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 33
    Par défaut
    dans main
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
      do
                              {
                                      Caractere = fgetc(fich); // On lit le caractère
                                      printf("%c", Caractere); // On l'affiche 
                                      Taille++;
                                      Calcul_Occurence_Caractere(Caractere,&Adr_Tableau_Asci,Taille);
                               } while (Caractere!= EOF);

  14. #14
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Taille représente bien le nombre d'éléments de ton tableau ?
    Tu l'augmentes que tu y ajoute ou non un élément ?
    Tu as essayé le pas à pas avec un débuggueur ?

  15. #15
    Membre actif
    Inscrit en
    Juin 2008
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 33
    Par défaut
    wi pour le moment j'augmente qq soit 'ajoute ou non
    j'essai le débuggueur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tableau_Asci[Taille+1]=Element_Tableau;
    ici l'erreur

  16. #16
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Citation Envoyé par twity Voir le message
    wi pour le moment j'augmente qq soit 'ajoute ou non
    j'essai le débuggueur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Tableau_Asci[Taille+1]=Element_Tableau;
    ici l'erreur
    Essaye déjà à la main ce que donnerai la traitement de "aab" ... quel est le contenu de ton tableau après avoir traité le b ...

  17. #17
    Membre actif
    Inscrit en
    Juin 2008
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 33
    Par défaut
    j compris c dans la fonction recherche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int Recherche_Caractere_TASCI(char Caractere, struct Noeud **Tableau_Asci  ,int Taille )
    {
    	int i;
    	for(i=0;i<Taille;i++)
    	 if(Tableau_Asci[i]->lettre==Caractere)
    	 {
     		return i;
     		break;
     	}
     	return -1;

  18. #18
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    Si le problème que tu cherches à résoudre n'est que compter le nombre d'occurences par caratères ASCII il est beaucoup (beaucoup) plus simple d'utiliser un tableau de 256 entiers comme unsigned occurence[256]; que tu initialiseras avec des 0. Ensuite si tu lis un caractère car alors tu incrémentes occurence[car]. À l'issue de la lecture de ton fichier le tableau contiendra à l'indice i le nombre de fois où tu auras rencontré le caractère de code ascii i.

    En revanche si le but de l'exercice est d'utiliser une sdd de type liste chainée, c'est une autre histoire.

  19. #19
    Membre actif
    Inscrit en
    Juin 2008
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 33
    Par défaut
    j'ai utilisé la methode avec un tableau de 256 entiers comme unsigned occurence[256]; est ca marche avec aucun problème mais je veux faire mnt avec l'allocation dynamique car dans un texte on peux trouver seulement qqle caractère pas le 256 caractère

  20. #20
    Membre Expert
    Avatar de kwariz
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Octobre 2011
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Chef de projet en SSII
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2011
    Messages : 898
    Par défaut
    ok, donc je suppose (d'après ton code) que tu as déclaré :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct Noeud {
      char lettre;
      unsigned occurence;
    };
    et tu voudrais avoir un tableau de struct Noeud que tu feras croitre dynamiquement en fonction de l'apparition de nouveau caractères.
    Une manière classique de définir une telle structure de donnée est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct s_growarray {
      size_t capacity;
      size_t length;
      struct Noeud* data;
    };
    capacity est la taille allouée pour le tableau, length est la taille utilisée. Cela va te permettre de ne pas multiplier les variables (une pour garder le tableau, une autre pour la taille utilisée et une dernière pour la taille allouée). Cela va aussi te permettre de ne pas avoir à reallouer à chaque nouvel élément : tu n'auras besoin de réallouer de la mémoire que lorsque tu insères un nouvel élément et que length==capacity.
    L'idéal en terme de performances amorties est de doubler la capacité quand tu doit augmenter la taille, mais ce n'est pas obligatoire, tu peux simplement l'augmenter d'une taille fixe.

    Si tu écris en plus les fonctions d'accès de base (création, libération, ajout, recherche, ...) aussi bien pour tes struct Noeud que pour struct s_growarray ton code sera bien lisible et propre (pas de malloc de struct noeud en plein milieu d'un if lors d'une insertion).

Discussions similaires

  1. Réponses: 1
    Dernier message: 21/12/2010, 16h57
  2. [Exchange 2003] problème de mise à jour de la liste d'adresse globale
    Par maikess dans le forum Exchange Server
    Réponses: 0
    Dernier message: 05/08/2010, 19h51
  3. Réponses: 1
    Dernier message: 31/03/2010, 17h57
  4. Réponses: 2
    Dernier message: 11/10/2008, 01h53
  5. Réponses: 2
    Dernier message: 12/02/2003, 16h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo