Comment modifier un tableau 2D transmis à une fonction?
Question
Pourquoi le code suivant me donne-t-il une erreur de segmentation?
#define MAXROWS 10
#define MAXCOLS 10
void getInput (int *data[MAXROWS][MAXCOLS]) {
int rows, cols;
int curRow, curCol;
printf ("How many rows and cols?");
scanf ("%d %d", rows, cols);
for (curRow = 0; curRow < rows; curRow++) {
for (curCol = 0; curCol < cols; curCol++) {
scanf ("%d", data[curRow][curCol]);
printf ("%d\n", *data[curRow][curCol]);
}
}
}
void main () {
int data[MAXROWS][MAXCOLS];
getInput (data);
}
Il semble que les instructions scanf
et printf
ne transmettent pas le type de données approprié, mais je ne peux pas déterminer ce qu'elles devrait être.
Comment puis-je le modifier pour qu'il fonctionne correctement?
La solution
Ceci déclare un tableau de tableaux MAXROWS
de pointeurs sur int
.
int *data[MAXROWS][MAXCOLS];
Cependant, dans une définition de fonction, les tableaux de niveau supérieur (de toute taille) sont équivalents aux pointeurs, car ils tombent toujours en pointeurs vers le type du membre du tableau lors du passage à une fonction.
La définition de votre fonction est donc équivalente à:
void getInput (int *(*data)[MAXCOLS])
i.e. un pointeur sur un tableau de pointeurs MAXCOLS
sur int
.
En l'état de votre code, vous n'initialisez jamais aucun des pointeurs int
du tableau, car vous transmettez un tableau 2d de int
en tant que pointeur sur un 2d tableau de int *
.
Ce que vous voulez probablement transmettre est un pointeur sur un tableau de MAXCOLS
int
:
void getInput (int (*data)[MAXCOLS])
ou de manière équivalente:
void getInput (int data[][MAXCOLS])
Ensuite, vous procédez comme suit:
int main(void)
{
int data[MAXROWS][MAXCOLS];
getInput(data);
return 0;
}
Vous passez ensuite votre tableau 2d en tant que pointeur sur son premier élément (un pointeur sur une ligne ou un tableau de MAXCOLS
int
s).
Si vous veillez à ce que le changement soit correct, assurez-vous de changer:
scanf ("%d", data[curRow][curCol]);
printf ("%d\n", *data[curRow][curCol]);
à:
scanf ("%d", &data[curRow][curCol]);
printf ("%d\n", data[curRow][curCol]);
Vérifiez également vos paramètres ici:
scanf ("%d %d", &rows, &cols);
Vous devez faire passer les pointeurs sur les lignes
et les colonnes
.
Assurez-vous d'ajouter des vérifications de limites à votre fonction d'entrée afin d'éviter de lire plus de lignes et de colonnes que MAXROWS
ou MAXCOLS
.
Autres conseils
scanf accepte l'adresse des variables et non son contenu:
void getInput (int data[][MAXCOLS]) {
int rows, cols;
int curRow, curCol;
printf ("How many rows and cols?");
scanf ("%d %d", &rows, &cols);
//scanf ("%d %d", &rows, &cols);
for (curRow = 0; curRow < rows; curRow++) {
for (curCol = 0; curCol < cols; curCol++) {
scanf ("%d", &data[curRow][curCol]);
printf ("%d\n", data[curRow][curCol]);
}
}
}
Il y avait quelques problèmes différents.
Premièrement, lorsque vous passez des tableaux à des fonctions, vous n’avez besoin que de la définition des dimensions N-1. Par exemple, si vous passez un tableau 3D, indiquez la taille des 2 dernières dimensions dans la fonction sig et laissez la première vide.
foo(int threeD[][10][15]);
Deuxièmement, scanf prend l'adresse de l'argument, qui ressemble à ceci pour votre tableau
&data[curRow][curCol]
Troisièmement, vous devez toujours vérifier l'étendue de votre saisie pour vous assurer qu'elle est valide:
if (rows > MAXROWS || cols > MAXCOLS) {
printf("Bad array dimensions\n");
return;
}
Quatrièmement, compilez toujours avec tous les avertissements activés - le compilateur vous avertira de beaucoup de choses:
gcc -Wall pass_array.c -o pass_array
.
#include <stdio.h>
#define MAXROWS 10
#define MAXCOLS 10
void getInput (int data[][MAXCOLS]) {
int rows, cols;
int curRow, curCol;
printf ("How many rows and cols?");
scanf ("%d %d", &rows, &cols);
if (rows > MAXROWS || cols > MAXCOLS) {
printf("Bad array dimensions\n");
return;
}
for (curRow = 0; curRow < rows; curRow++) {
for (curCol = 0; curCol < cols; curCol++) {
scanf ("%d", &data[curRow][curCol]);
printf ("%d\n", data[curRow][curCol]);
}
}
}
int main () {
int data[MAXROWS][MAXCOLS];
getInput (data);
return 0;
}