tableau multidimensionnel malloquant en fonction

J’essaie d’allouer un tableau 2d dans un programme C. Cela fonctionne bien dans la fonction principale comme ceci (comme expliqué ici ):

#include  #include  int main(int argc, char ** argv) { int ** grid; int i, nrows=10, ncols=10; grid = malloc( sizeof(int *) * nrows); if (grid == NULL){ printf("ERROR: out of memory\n"); return 1; } for (i=0;i<nrows;i++){ grid[i] = malloc( sizeof(int) * ncols); if (grid[i] == NULL){ printf("ERROR: out of memory\n"); return 1; } } printf("Allocated!\n"); grid[5][6] = 15; printf("%d\n", grid[5][6]); return 0; } 

Mais comme je dois le faire plusieurs fois avec différents tableaux, je tentais de déplacer le code dans une fonction distincte.

 #include  #include  int malloc2d(int ** grid, int nrows, int ncols){ int i; grid = malloc( sizeof(int *) * nrows); if (grid == NULL){ printf("ERROR: out of memory\n"); return 1; } for (i=0;i<nrows;i++){ grid[i] = malloc( sizeof(int) * ncols); if (grid[i] == NULL){ printf("ERROR: out of memory\n"); return 1; } } printf("Allocated!\n"); return 0; } int main(int argc, char ** argv) { int ** grid; malloc2d(grid, 10, 10); grid[5][6] = 15; printf("%d\n", grid[5][6]); return 0; } 

Cependant, bien qu’il ne se plaint pas lors de l’allocation, j’obtiens une erreur de segmentation lors de l’access au tableau. J’ai lu différents articles sur des tableaux délabrés et des sujets similaires, mais je ne comprends toujours pas comment résoudre ce problème. J’imagine que je ne passe pas correctement le tableau 2d à la fonction.

Merci beaucoup.

    Ce n’est pas un tableau multidimensionnel; c’est un tableau à une dimension contenant des pointeurs sur des tableaux à une dimension. Les tableaux multidimensionnels ne contiennent pas de pointeurs. ce sont des blocs de mémoire simples.

    Votre problème ici est que vous avez un pointeur sur un pointeur et que vous essayez de le renvoyer à partir de votre fonction via un paramètre. Si vous voulez faire cela, vous aurez besoin d’un pointeur vers un pointeur vers un pointeur en tant que paramètre, et vous devrez passer l’adresse d’un pointeur à un pointeur vers la méthode. Si vous ne le faites pas, vous ne modifiez pas la valeur de la variable grid dans main – vous modifiez celle qui a été copiée en tant que paramètre dans la fonction malloc2d . Étant donné que la grid de main n’est pas initialisée, vous obtenez un comportement indéfini.

    Voici un exemple de ce que je veux dire comme solution:

     #include  #include  int malloc2d(int *** grid, int nrows, int ncols){ int i; *grid = malloc( sizeof(int *) * nrows); if (*grid == NULL){ printf("ERROR: out of memory\n"); return 1; } for (i=0;i 

    Notes complémentaires:

    • Si une seule allocation échoue, vous divulguez l'allocation pour le premier tableau, ainsi que les allocations pour toutes les lignes précédentes. Vous devez appeler free avant de revenir.
    • Vous revenez à travers un paramètre, même si vous n'y êtes pas obligé. Si j'écrivais ceci, je ferais en sorte que la méthode retourne int ** et signalerais une erreur en renvoyant 0

    Voici votre fonction, fixée:

     int malloc2d(int *** grid, int nrows, int ncols){ int i; *grid = (int**)malloc( sizeof(int *) * nrows); if (*grid == NULL){ printf("ERROR: out of memory\n"); return 1; } for (i=0;i 

    Notez que la fonction reçoit maintenant un int*** et que vous passez l' adresse de votre int** à la fonction. La fonction déréférence alors le int*** pour y mettre l'adresse du bloc de mémoire alloué.

    C est passe par valeur. Et pour résumer l’erreur que vous faites, cet exemple devrait être utile –

     void foo( int *temp ) { temp = malloc(sizeof(int)) ; // temp is assigned to point to new location but the actual variable // passed from main do not point to the location temp is pointing to. *temp = 10 ; } int main() { int *ptr ; foo( ptr ) ; // ptr is still unintialized *ptr = 5 ; // Segmentation fault or Undefined behavior return 0; } 

    Donc, vous devriez plutôt faire –

     void foo( int **temp ) { *temp = malloc(sizeof (int) ); // ... } 

    Et maintenant, appelez la fonction foo(&ptr); dans la fonction main() .

    Si vous souhaitez toujours que malloc2d renvoie un code d’état, le paramètre doit être de type int*** :

     int malloc2d(int *** grid, int nrows, int ncols){ 

    Et vous devez utiliser *grid pour faire référence au tampon fourni:

      int i; *grid = malloc( sizeof(int *) * nrows); if (*grid == NULL){ printf("ERROR: out of memory\n"); return 1; } for (i=0;i 

    Ensuite, lorsque vous appelez malloc2d , transmettez-lui l'adresse d'un int** à remplir:

     int ** grid; malloc2d(&grid, 10, 10); 

    C est en fait toujours passer par valeur. Ainsi, lorsque vous transmettez ‘grid’, vous transmettez une valeur et la fonction modifie sa propre copie locale. Essayez plutôt de passer à ‘& grid’ et modifiez malloc2d de manière appropriée.

    Ce n’est pas votre problème de faute de segmentation, mais vous devriez vraiment envisager d’utiliser un seul appel malloc pour allouer tous les besoins en espace mémoire nécessaires par grid.

     grid = malloc (nrows * ncols * sizeof(int *)) 

    Regardez la réponse de Bill ONeary concernant le pointeur du pointeur du pointeur.

    Shorter devrait être en dessous, avec des valeurs libres (!) Et initialisées pour chaque élément de la grid:

     #include  #include  #define NROWS 10 #define NCOLS 10 int main() { int (* grid)[NCOLS] = calloc(NROWS,sizeof*grid); /* no more needed here malloc2d(grid, 10, 10); */ grid[5][6] = 15; printf("%d\n", grid[5][6]); free(grid); /* every c/malloc need a free */ return 0; }