Come posso modificare un array 2d passato a una funzione?
Domanda
Perché il seguente codice mi dà un errore di segmentazione?
#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);
}
Sembra che le istruzioni scanf
e printf
non ricevano il giusto tipo di dati, ma non riesco a capire cosa dovrebbe essere.
Come posso cambiarlo in modo che funzioni correttamente?
Soluzione
Questo dichiara una matrice di MAXROWS
matrici di puntatori su int
.
int *data[MAXROWS][MAXCOLS];
Tuttavia, in una definizione di funzione, gli array di livello superiore (di qualsiasi dimensione) sono equivalenti ai puntatori poiché gli array decadono sempre in puntatori al tipo di membro dell'array quando passano a una funzione.
Quindi la definizione della tua funzione è equivalente a:
void getInput (int *(*data)[MAXCOLS])
vale a dire. un puntatore a una matrice di MAXCOLS
puntatori a int
.
Allo stato attuale del codice, non si inizializza mai nessuno dei puntatori int
nella matrice, poiché si passa una matrice 2d di int
come puntatore a una 2d array di int *
.
Quello che probabilmente vuoi passare è un puntatore a una matrice di MAXCOLS
int
:
void getInput (int (*data)[MAXCOLS])
o equivalentemente:
void getInput (int data[][MAXCOLS])
Quindi fai quanto segue:
int main(void)
{
int data[MAXROWS][MAXCOLS];
getInput(data);
return 0;
}
Stai quindi passando il tuo array 2d come puntatore al suo primo elemento (un puntatore a una riga o un array di MAXCOLS
int
s).
Se ti assicuri che il cambiamento sia sicuro di cambiare:
scanf ("%d", data[curRow][curCol]);
printf ("%d\n", *data[curRow][curCol]);
a:
scanf ("%d", &data[curRow][curCol]);
printf ("%d\n", data[curRow][curCol]);
Inoltre, controlla i tuoi parametri qui:
scanf ("%d %d", &rows, &cols);
Devi passare i puntatori a righe
e cols
.
Assicurati di aggiungere alcuni limiti controllando la tua funzione di input in modo da non tentare di leggere più righe e colonne di MAXROWS
o MAXCOLS
.
Altri suggerimenti
scanf accetta l'indirizzo delle variabili, non il suo contenuto:
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]);
}
}
}
Ci sono stati alcuni problemi diversi.
Innanzitutto, quando si passano le matrici alle funzioni è necessaria solo la definizione delle dimensioni N-1. Ad esempio, se si sta passando un array 3D, si inserirà la dimensione delle ultime 2 dimensioni nella funzione sig e si lascerà il primo vuoto.
foo(int threeD[][10][15]);
In secondo luogo, scanf prende l'indirizzo dell'argomento, che per l'array è simile a questo
&data[curRow][curCol]
Terzo, dovresti sempre controllare l'intervallo di input per assicurarti che sia valido:
if (rows > MAXROWS || cols > MAXCOLS) {
printf("Bad array dimensions\n");
return;
}
Quarto, compilare sempre con tutti gli avvisi attivati: il compilatore ti avviserà di assegnare queste cose:
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;
}