ce petit code ne fonctionne pas, pourquoi ?

ce petit code ne fonctionne pas, pourquoi ? - C - Programmation

Marsh Posté le 30-05-2015 à 21:57:16    

Bonjour a tous, c'est mon premier post sur ce site. Je suis vraiment bloqué car je n'arrive pas a créer mon tableau de dimension 4x4x2 qui doit etre alloué dynamiquement. Je joins donc le code dans l'espoir que quelqu'un puisse voir ce qui m'a échappé :)  
 
 
 
char ** creation(){
     char **tab;
     tab= malloc (4*sizeof (char*));
     int i;
     for(i=0;i<4;i++){
 
            tab= malloc (4*sizeof(char));
      }
     int j;
     for(i=0;i<4;i++){
            for(j=0;j<4;j++){
                    tab[j]=malloc (2*sizeof(char));
            }
     }
     return tab;
}


Message édité par zachou2 le 30-05-2015 à 22:01:05
Reply

Marsh Posté le 30-05-2015 à 21:57:16   

Reply

Marsh Posté le 30-05-2015 à 22:57:44    

Tes spécification sont trop vague.
Perso j'ai fait ça déjà.

Code :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. int main (void) {
  4.  int Lines = 4;
  5.  int Columns = 4;
  6.  int Record = 2;
  7.  int * Tab[Lines][Columns][Record];
  8.  
  9.  
  10.  int L, C, R = 1;
  11.  
  12.  for (L = 1; L <= Lines; L++)
  13.    {
  14.      for (C = 1; C <= Columns; C++)
  15.        {
  16.          for (R = 1; R <= Record; R++)
  17.            {
  18.  
  19.              Tab[L][C][R] = malloc (1 * sizeof (int));
  20.              printf("Quel âge avez vous ?\n" );
  21.              scanf("%d", &Tab[L][C][R]);
  22.  
  23.            }
  24.        }
  25.    }
  26.  
  27.  /* for (L = 1; L <= Lines; L++) */
  28.  /*   { */
  29.  /*     for (C = 1; C <= Columns; C++) */
  30.  /*    { */
  31.  /*      for (R = 1; R <= Record; R++) */
  32.  /*        { */
  33.  
  34.  
  35.  /*          printf("Line %i, Columns %i Record %i vous avez %i ans\n", L, C, R, Tab[L][C][R]); */
  36.  /*        } */
  37.  /*    } */
  38.  /*   } */
  39.  return 0;
  40. }


 
Après si tu veux faire du dynamique c'est que tu connais pas les dimensions, ou alors, j'ai bon.


---------------
Toute expression prend un sens spirituel qui nous influence dans notre quête de l'Homme.
Reply

Marsh Posté le 30-05-2015 à 23:28:44    

Ca compile sans warnings, ça tourne, mais c'est vraiment sans garantie, j'ai pas touché à ces trucs depuis une éternité...
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. char ***creation()
  4. {
  5.     char ***tab;
  6.     int i,j;
  7.     tab=malloc(4*sizeof(char**));
  8.     if(!tab) exit(1);
  9.     for(i=0;i<4;i++)
  10.     {
  11.         tab[i]=malloc(4*sizeof(char*));
  12.         if(!tab[i]) exit(2);
  13.         for(j=0;j<4;j++)
  14.         {
  15.             tab[i][j]=malloc(2*sizeof(char));
  16.             if(!tab[i][j]) exit(3);
  17.         }
  18.     }
  19.     return tab;
  20. }
  21. void suppression(char *** tab)
  22. {
  23.     int i,j;
  24.     for(i=0;i<4;i++)
  25.     {
  26.         for(j=0;j<4;j++)
  27.         {
  28.             free(tab[i][j]);
  29.         }
  30.         free(tab[i]);
  31.     }
  32.     free(tab);
  33. }
  34. int main()
  35. {
  36.     int i,j,k;
  37.     char ***ptr;
  38.     char n=0;
  39.     ptr=creation();
  40.     for(i=0;i<4;i++)
  41.     {
  42.         for(j=0;j<4;j++)
  43.         {
  44.             for(k=0;k<2;k++)
  45.             {
  46.                 ptr[i][j][k]=n++;
  47.             }
  48.         }
  49.     }
  50.     suppression(ptr);
  51.     return 0;
  52. }


 
Pour les constantes vaut mieux mettre des #define, c'est plus propre.

Reply

Marsh Posté le 30-05-2015 à 23:39:18    

Même sans regarder les détails genre le nombre d'étoiles on voit que le code ne peut être bon:

Code :
  1. tab= malloc (4*sizeof (char*));


Tu alloues de la mémoire et tu stockes un pointeur correspondant. Soit.
 
Mais alors là

Code :
  1. for(i=0;i<4;i++){
  2.      tab= malloc (4*sizeof(char));
  3. }


tu refais la même chose 4 fois de suite en ne gardant qu'un pointeur vers la dernière adresse mémoire que malloc() retourne. Autrement dit tu alloues de la mémoire sans sauvegarder l'adresse de cette dernière, ça s'appelle un memory-leak...
 
Heu désolé par l'anneau de l'ia, mais ton code c'est un peu n'importe quoi: Tu fais un tableau de pointeurs en heu "semi-statique" (https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html) puis pour chaque pointeur tu alloues de la mémoire pour un seul int que tu utilises sans vérifier que malloc() a retourné une adresse valide... Autant faire directement

Code :
  1. int Tab[Lines][Columns][Record];

et oublier le malloc()...
D'ailleurs ton code est faux,

Code :
  1. scanf("%d", &Tab[L][C][R]);

il faut enlever le '&' puisque Tab[][][] est déjà un pointeur vers un int.
 
(En espérant ne pas me tromper, bonne nuit...)
 
edit: Aie! J'avais même pas vu mais GCC me l'a fait remarquer: Les indices de tes tableaux!!!  

Code :
  1. for (L = 0; L < Lines; L++)
  2.         {
  3.           for (C = 0; C < Columns; C++)
  4.             {
  5.               for (R = 0; R < Record; R++)



Message édité par rat de combat le 30-05-2015 à 23:41:47
Reply

Marsh Posté le 31-05-2015 à 18:58:13    

Il faut toujours compiler avec Wall :)

Reply

Marsh Posté le 31-05-2015 à 19:04:47    

Un grand merci a toi rat de combat ! Ton code m'a beaucoup aidé et tes indications m'ont fait me rendre compte de mes erreurs.
Encore merci !

Reply

Marsh Posté le 31-05-2015 à 19:51:36    

Ce truc piqué à StackOverflow est particulièrement clair sur la question:
 
 
A two-dimensional array:

int foo[5][4];

is nothing more or less than an array of arrays:

typedef int row[4];   /* type "row" is an array of 4 ints */
row foo[5];           /* the object "foo" is an array of 5 rows */


There are no pointer objects here, either explicit or implicit.
Arrays are not pointers. Pointers are not arrays.
 
What often causes confusion is that an array expression is, in most contexts, implicitly converted to a pointer to its first element. (And a separate rule says that what looks like an array parameter declaration is really a pointer declaration, but that doesn't apply in this example.) An array object is an array object; declaring such an object does not create any pointer objects. Referring to an array object can create a pointer value (the address of the array's first element), but there is no pointer object stored in memory.
 
The array object foo is stored in memory as 5 contiguous elements, where each element is itself an array of 4 contiguous int elements; the whole thing is therefore stored as 20 contiguous int objects.
 
The indexing operator is defined in terms of pointer arithmetic; x[y] is equivalent to *(x + y). Typically the left operand is going to be either a pointer expression or an array expression; if it's an array expression, the array is implicitly converted to a pointer.
 
So foo[x][y] is equivalent to *(foo[x] + y), which in turn is equivalent to *(*(foo + x) + y). (Note that no casts are necessary.) Fortunately, you don't have to write it that way, and foo[x][y] is a lot easier to understand.
 
Note that you can create a data structure that can be accessed with the same foo[x][y] syntax, but where foo really is a pointer to pointer to int. (In that case, the prefix of each [] operator is already a pointer expression, and doesn't need to be converted.) But to do that, you'd have to declare foo as a pointer-to-pointer-to-int:

int **foo;

and then allocate and initialize all the necessary memory. This is more flexible than int foo[5][4], since you can determine the number of rows and the size (or even existence) of each row dynamically.
 
A+,


Message édité par gilou le 31-05-2015 à 19:52:25

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 01-06-2015 à 22:03:03    

antac a écrit :

Il faut toujours compiler avec Wall :)


Toutafé! :)
 
Pour ceux qui pourraient tomber dessus sans comprendre: Il faut toujours demander au compilateur d'afficher le maximum de warnings. Pour le GCC pour cela il faut rajouter -Wall dans les paramètres.

Reply

Marsh Posté le 02-06-2015 à 09:05:18    

Citation :

Pour ceux qui pourraient tomber dessus sans comprendre: Il faut toujours demander au compilateur d'afficher le maximum de warnings. Pour le GCC pour cela il faut rajouter -Wall dans les paramètres.


pour Visual C aussi !

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed