¿Cómo puedo modificar una matriz 2D pasada a una función?
Pregunta
¿Por qué el siguiente código me da un error de segmentación?
#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);
}
Parece ser que las declaraciones scanf
e printf
no están recibiendo el tipo de datos correcto, pero no puedo averiguar qué debería ser.
¿Cómo puedo cambiarlo para que funcione correctamente?
Solución
Esto declara una matriz de MAXROWS
matrices de punteros a int
.
int *data[MAXROWS][MAXCOLS];
Sin embargo, en una definición de función, las matrices de nivel superior (de cualquier tamaño) son equivalentes a los punteros porque las matrices siempre decaen a punteros al tipo del miembro de la matriz al pasar a una función.
Entonces, la definición de su función es equivalente a:
void getInput (int *(*data)[MAXCOLS])
es decir un puntero a una matriz de punteros MAXCOLS
a int
.
Tal como está su código, nunca inicializa ninguno de los punteros int
en la matriz, ya que pasa una matriz 2d de int
s como puntero a una 2d matriz de int *
.
Lo que probablemente quiera pasar es un puntero a una matriz de MAXCOLS
int
:
void getInput (int (*data)[MAXCOLS])
o equivalente:
void getInput (int data[][MAXCOLS])
Luego haces lo siguiente:
int main(void)
{
int data[MAXROWS][MAXCOLS];
getInput(data);
return 0;
}
Luego está pasando su matriz 2D como puntero a su primer elemento (un puntero a una fila o una matriz de MAXCOLS
int
s).
Si se asegura de cambiar asegúrese de cambiar:
scanf ("%d", data[curRow][curCol]);
printf ("%d\n", *data[curRow][curCol]);
a:
scanf ("%d", &data[curRow][curCol]);
printf ("%d\n", data[curRow][curCol]);
Además, verifique sus parámetros aquí:
scanf ("%d %d", &rows, &cols);
Debe pasar punteros a filas
y cols
.
Asegúrese de agregar algunos controles de límites a su función de entrada para que no intente leer más filas y columnas que MAXROWS
o MAXCOLS
.
Otros consejos
scanf acepta la dirección de variables, no el contenido de la misma:
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]);
}
}
}
Hubo algunos problemas diferentes.
Primero, al pasar matrices a funciones solo necesita la definición de dimensiones N-1. Por ejemplo, si está pasando una matriz 3D, colocaría el tamaño de las 2 últimas dimensiones en la función sig y dejaría la primera vacía.
foo(int threeD[][10][15]);
Segundo, scanf toma la dirección del argumento, que para su matriz se ve así
&data[curRow][curCol]
Tercero, siempre debe verificar el rango de su entrada para asegurarse de que sea válido:
if (rows > MAXROWS || cols > MAXCOLS) {
printf("Bad array dimensions\n");
return;
}
Cuarto, compile siempre con todas las advertencias activadas: el compilador le advertirá sobre todas estas cosas:
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;
}