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?

È stato utile?

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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top