Partage
  • Partager sur Facebook
  • Partager sur Twitter

Allocation dynamique Tableau de charactères

    7 septembre 2021 à 14:36:34

    Bonjour, 

    j'essaye de faire un code qui remplit et adapte la taille d'un tableau de characées alloué dynamiquement mais j'ai des problème de mémoire.

    Pouvez vous m'aider s'il vous plait sur ce sujet ? 

    Merci

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #include <stdarg.h>
    #include <inttypes.h>
    #include <unistd.h>
    #include <sys/time.h>
    
    
    
    int fct1( char **rp,int oldSize)
    {
        int newSize=5;
        rp =(char**) realloc (rp, newSize * sizeof(char) );
        if (rp==NULL)
        {
            printf(" \n Allocation problem \n");
            exit(0);
        }
        for(int i=0;i<newSize;i++)
        {
            rp[i]=(char*)malloc(sizeof(char)*4);
        }
    
        for(int i=0; i<newSize; i++)
        {   
            rp[i]="AAA\0";
            printf(" \n Apres remplissage : rp[%d] = %s",i,rp[i]);
        }
        return newSize;
    }
    
    
    int fct2( char **rp,int oldSize)
    {
        int newSize=10;
        rp =(char**) realloc (rp, newSize * sizeof(char) );
        if (rp==NULL)
        {
            printf(" \n Allocation problem \n");
            exit(0);
        }
        for(int i=0;i<newSize;i++)
        {
            rp[i]=(char*)malloc(sizeof(char) *4);
        }
        for(int i=0; i<newSize; i++)
        {   
            rp[i]="BBB\0";
            printf(" \n Apres remplissage : rp[%d] = %s",i,rp[i]);
        }
        return newSize;
    }
    
    
    int main()
    {
        int oldSize=1;
        char **tab=NULL;
        tab=(char**)malloc(oldSize*sizeof(char*));
        
        if(tab==NULL)
        {
            printf("Problème de Malloc tab \n");
            exit(0);
        }
        else
        {
            for(int i=0;i<oldSize;i++)
            {
                tab[i]=(char*)malloc(sizeof(char)*4);
            }
        }
        
        printf("Initialisation\n");
        for(int i=0;i<oldSize;i++)
        {
            tab[i]="000\0";
        }
    
        int newSize=fct1(tab,oldSize);
        
        printf(" \n\n \t\tApres le passage par la fct1 : tab vaut \n");
        
        for(int i=0; i<newSize;i++)
        {
            printf(" \ntab[%d] = %s",i,tab[i]);
        }
        
        oldSize=newSize;
        
        newSize=fct2(tab,oldSize);
        
        printf(" \n\n \t\tApres le passage par la fct2 : tab vaut \n");
        
        for(int i=0; i<newSize;i++)
        {
            printf(" \ntab[%d] = %s",i,tab[i]);
        }
        
        return 0;
    }
    



    • Partager sur Facebook
    • Partager sur Twitter
      7 septembre 2021 à 14:46:56

      Hello,

      La ligne 79 pose problème: tu perds l'adresse retournée par le malloc() de la ligne 72. Tu dois utiliser strcpy(). Idem lignes 28 et 50.

      Autre problème, et je m'arrêterai là: la variable rp que reçoivent fct1() et fct2() n'est qu'une copie de tab. Tu peux modifier rp autant que tu veux dans les fonctions, la variable tab du main() restera inchangée. Par contre, si tu passais l'adresse de tab aux fonctions

      int fct(char ***rp,....) {
          ....
      }
      
      int main() {
          char **tab;
          ....
          int x=fct(&tab,....);
          ....
      }

      ça aiderait :-)

      PS: en C, on ne cast pas le retour de malloc(). Si cela génère une erreur de compilation sans le cast, c'est que tu compiles en C++ et pas en C

      __________________________________________________________________________

      Edit pour le fun:

      Aghiles_D a écrit:

      Bonjour, 

      j'essaye de faire un code qui remplit et adapte la taille d'un tableau de characées alloué dynamiquement mais j'ai des problème de mémoire.

      L'age, peut-être ?

      -
      Edité par edgarjacobs 7 septembre 2021 à 14:57:54

      • Partager sur Facebook
      • Partager sur Twitter

      On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

        7 septembre 2021 à 15:37:01

        edgarjacobs a écrit:

        Hello,

        La ligne 79 pose problème: tu perds l'adresse retournée par le malloc() de la ligne 72. Tu dois utiliser strcpy(). Idem lignes 28 et 50.

        Autre problème, et je m'arreterai là: la variable rp que reçoivent fct1() et fct2() n'est qu'une copie de tab. Tu peux modifier rp autant que tu veux dans les fonction la variable tab du main() restera inchangée. Par contre, si tu passais l'adresse de tab aux fonctions

        int fct(char ***tab,....) {
            ....
        }
        
        int main() {
            char **tab;
            ....
            int x=fct1(&tab,....);
            ....
        }

        ça aiderait :-)

        PS: en C, on ne cast pas le retour de malloc(). Si cela génère une erreur de compilation, c'est que tu compiles en C++ et pas en C

        -
        Edité par edgarjacobs il y a moins de 30s

        Merci pour ton aide, 

        J'ai appliqué ce que tu m'as dit, mais hélas j'ai toujours la même erreur ! 

        Je pense que je suis perdu dans ces histoires de pointeurs ....

        • Partager sur Facebook
        • Partager sur Twitter
          7 septembre 2021 à 16:16:25

          Aghiles_D a écrit:

          J'ai appliqué ce que tu m'as dit, mais hélas j'ai toujours la même erreur ! 

          Probablement que non ! 

          Mais quel est donc cette erreur ? Un seg fault ?

          Je te donne un exercice simple sur ton problème, complète moi ce code afin qu'il modifie la valeur de x via la fonction :

          #include <stdio.h>
          
          void fct( /* ?param? */ )
          {
              // Met la valeur de x à 10
          }
          
          int main(void)
          {
              int x = 0;
              
              fct( /* ??? */ );
              
              printf("%d", x);     
              
              return 0;
          }
          



          • Partager sur Facebook
          • Partager sur Twitter
          ...
            7 septembre 2021 à 16:39:25

            rouIoude a écrit:

            Aghiles_D a écrit:

            J'ai appliqué ce que tu m'as dit, mais hélas j'ai toujours la même erreur ! 

            Probablement que non ! 

            Mais quel est donc cette erreur ? Un seg fault ?

            Je te donne un exercice simple sur ton problème, complète moi ce code afin qu'il modifie la valeur de x via la fonction :

            #include <stdio.h>
            
            void fct( /* ?param? */ )
            {
                // Met la valeur de x à 10
            }
            
            int main(void)
            {
                int x = 0;
                
                fct( /* ??? */ );
                
                printf("%d", x);     
                
                return 0;
            }
            
            ça donne ça normalement  : 
            #include <stdio.h>
            
            void fct(int *a)
            {
                *a=10; // Met la valeur de x à 10
            }
            
            int main(void)
            {
                int x = 0;
                
                fct(&x);
                
                printf("%d", x);     
                
                return 0;
            }


            • Partager sur Facebook
            • Partager sur Twitter
              7 septembre 2021 à 17:30:21

              Et bien pour un pointeur, c'est pareil, tu dois envoyer l'adresse du pointeur à la fonction pour qu'elle puisse le modifier.

              Une autre solution est de retourner la nouvelle adresse et de l'affecter au pointeur.

              • Partager sur Facebook
              • Partager sur Twitter
              ...
                7 septembre 2021 à 20:19:11

                Un exemple, en sachant que realloc() réagit comme malloc() lorsque le pointeur à réallouer est NULL. Ce code fait 5 réallocations de 3 éléments de ESIZE taille

                #include <stdio.h>
                #include <stdlib.h>
                
                #define ESIZE		16
                
                
                void DisplayArray(char **array,int nelem) {
                	for(int i=0;i<nelem;i++)
                		printf("%s\n",array[i]);
                	puts("------------------------");
                }
                
                
                int ReallocArray(char ***array,int cursize,int size_to_add) {
                	int totsize=cursize+size_to_add;
                	*array=realloc(*array,totsize*sizeof(**array));		// sizeof(**array) <==> sizeof(char *)
                	for(int i=cursize;i<totsize;i++)
                		(*array)[i]=malloc(ESIZE);
                	
                	return(totsize);
                }
                
                
                void FillArray(char **array,int bi,int bs,int ref) {
                	for(int i=bi;i<bs;i++)
                		sprintf(array[i],"%02d - %02d",ref,i);
                }
                
                
                int main(void) {
                	char **array=NULL;
                	int cursize,oldsize;
                	
                	oldsize=0;
                	for(int i=0;i<5;i++){
                		cursize=ReallocArray(&array,oldsize,3);
                		FillArray(array,oldsize,cursize,i);
                		DisplayArray(array,cursize);
                		oldsize=cursize;
                	}
                	
                	for(int i=0;i<cursize;i++)
                		free(array[i]);
                	
                	return(0);
                }

                Comme l'a écrit rouloude, j'envoie l'adresse du pointeur à la fonction de réallocation, ce qui permet de le modifier

                -
                Edité par edgarjacobs 7 septembre 2021 à 20:24:32

                • Partager sur Facebook
                • Partager sur Twitter

                On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                  7 septembre 2021 à 21:28:14

                  edgarjacobs a écrit:

                  Un exemple, en sachant que realloc() réagit comme malloc() lorsque le pointeur à réallouer est NULL. Ce code fait 5 réallocations de 3 éléments de ESIZE taille

                  #include <stdio.h>
                  #include <stdlib.h>
                  
                  #define ESIZE		16
                  
                  
                  void DisplayArray(char **array,int nelem) {
                  	for(int i=0;i<nelem;i++)
                  		printf("%s\n",array[i]);
                  	puts("------------------------");
                  }
                  
                  
                  int ReallocArray(char ***array,int cursize,int size_to_add) {
                  	int totsize=cursize+size_to_add;
                  	*array=realloc(*array,totsize*sizeof(**array));		// sizeof(**array) <==> sizeof(char *)
                  	for(int i=cursize;i<totsize;i++)
                  		(*array)[i]=malloc(ESIZE);
                  	
                  	return(totsize);
                  }
                  
                  
                  void FillArray(char **array,int bi,int bs,int ref) {
                  	for(int i=bi;i<bs;i++)
                  		sprintf(array[i],"%02d - %02d",ref,i);
                  }
                  
                  
                  int main(void) {
                  	char **array=NULL;
                  	int cursize,oldsize;
                  	
                  	oldsize=0;
                  	for(int i=0;i<5;i++){
                  		cursize=ReallocArray(&array,oldsize,3);
                  		FillArray(array,oldsize,cursize,i);
                  		DisplayArray(array,cursize);
                  		oldsize=cursize;
                  	}
                  	
                  	for(int i=0;i<cursize;i++)
                  		free(array[i]);
                  	
                  	return(0);
                  }

                  Comme l'a écrit rouloude, j'envoie l'adresse du pointeur à la fonction de réallocation, ce qui permet de le modifier

                  -

                  Merci pour ton code !

                  Je me suis inspiré pour refaire mon code à moi , par contre j'ai une question :

                  Pour mon cas quand je free a la fin chaque ligne seule mon code crash, par contre quand je free direteent le tableau en entier ça marche  ! je trouve ça bizzar.

                  Pour ton code, il ne manque pas un free(array) à la fin ?

                  Voici mon code :

                  #include <stdio.h>
                  #include <stdlib.h>
                  #include <string.h>
                  #include <time.h>
                  #include <stdarg.h>
                  #include <inttypes.h>
                  #include <unistd.h>
                  #include <sys/time.h>
                  
                  
                  
                  void fct1( char ***rp,int oldSize,int newSize)
                  {
                      for(int i=0; i<oldSize; i++)
                      {   
                          printf(" \n Avant remplissage : rp[%d] = %s",i,(*rp)[i]);
                      }
                      printf("\n------------------------------------------------------\n");
                  
                      *rp =realloc (*rp, newSize * sizeof(**rp) );
                      if (rp==NULL)
                      {
                          printf(" \n Allocation problem \n");
                          exit(0);
                      }
                      for(int i=0;i<newSize;i++)
                      {
                          (*rp)[i]=malloc(sizeof(char)*4);
                      }
                  
                      for(int i=0; i<newSize; i++)
                      {   
                          (*rp)[i]="111\0";
                          printf(" \n Apres remplissage : rp[%d] = %s",i,(*rp)[i]);
                      }
                  }
                  
                  
                  
                  int main()
                  {
                      int oldSize=0;
                      char **tab=NULL;
                  
                       tab=(char**)malloc(oldSize*sizeof(char*));
                      
                       if(tab==NULL)
                       {
                           printf("Problème de Malloc tab \n");
                           exit(0);
                       }
                       else
                       {
                           for(int i=0;i<oldSize;i++)
                           {
                               tab[i]=(char*)malloc(sizeof(char)*4);
                           }
                      }
                      
                      printf("Initialisation\n");
                      for(int i=0;i<oldSize;i++)
                      {
                          tab[i]="000\0";
                      }
                      printf("\n------------------------------------------------------\n");
                  
                      printf(" \n\n \t\tAvant le passage par la fct1 : tab vaut \n");
                      
                      for(int i=0; i<oldSize;i++)
                      {
                          printf(" \ntab[%d] = %s",i,tab[i]);
                      }
                      
                      int newSize=5;
                      
                      fct1(&tab,oldSize,newSize);
                      printf("\n------------------------------------------------------\n");
                  
                      printf(" \n\n \t\tApres le 1 er  passage par la fct : tab vaut \n");
                      
                      for(int i=0; i<newSize;i++)
                      {
                          printf(" \ntab[%d] = %s",i,tab[i]);
                      }
                      
                      oldSize=newSize;
                      newSize=10;
                      
                      fct1(&tab,oldSize,newSize);
                      
                      printf("\n------------------------------------------------------\n");
                  
                      printf(" \n\n \t\tApres le 1 er  passage par la fct : tab vaut \n");
                      
                      for(int i=0; i<newSize;i++)
                      {
                          printf(" \ntab[%d] = %s",i,tab[i]);
                      }
                      
                  /*    for( int i=0; i<newSize; i++)
                      {
                          free((*tab)[i]);
                      }*/
                      
                      free(tab);
                      
                      printf("\n fin du code");
                  
                      
                      return 0;
                  }



                  Edité par edgarjacobs il y a 16 minutes



                  • Partager sur Facebook
                  • Partager sur Twitter
                    7 septembre 2021 à 23:30:32

                    edgarjacobs a écrit:

                    La ligne 79 pose problème: tu perds l'adresse retournée par le malloc() de la ligne 72. Tu dois utiliser strcpy(). Idem lignes 28 et 50.

                    Comment veux-tu faire un free() d'une adresse que malloc() n'a pas attribuée ?

                    Et oui, tu as raison, il manque une free(array)

                    -
                    Edité par edgarjacobs 7 septembre 2021 à 23:32:08

                    • Partager sur Facebook
                    • Partager sur Twitter

                    On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                      9 septembre 2021 à 18:04:08

                      edgarjacobs a écrit:

                      edgarjacobs a écrit:

                      La ligne 79 pose problème: tu perds l'adresse retournée par le malloc() de la ligne 72. Tu dois utiliser strcpy(). Idem lignes 28 et 50.

                      Comment veux-tu faire un free() d'une adresse que malloc() n'a pas attribuée ?

                      Et oui, tu as raison, il manque une free(array)

                      -
                      Edité par edgarjacobs 7 septembre 2021 à 23:32:08

                      Merci pour ton aide !  :) 

                      Il me faut vraiment un cour qui explique bien les pointeurs pas seulement les int *a=&b 



                      • Partager sur Facebook
                      • Partager sur Twitter
                        9 septembre 2021 à 18:58:30

                        Le cours de Zeste de Savoir est très bon:
                        https://zestedesavoir.com/tutoriels/755/le-langage-c-1/1043_aggregats-memoire-et-fichiers/4277_les-pointeurs/
                        • Partager sur Facebook
                        • Partager sur Twitter

                        Le Tout est souvent plus grand que la somme de ses parties.

                          10 septembre 2021 à 12:33:04

                          PierrotLeFou a écrit:

                          Le cours de Zeste de Savoir est très bon:
                          https://zestedesavoir.com/tutoriels/755/le-langage-c-1/1043_aggregats-memoire-et-fichiers/4277_les-pointeurs/


                          Merci !
                          • Partager sur Facebook
                          • Partager sur Twitter

                          Allocation dynamique Tableau de charactères

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown