How can I modify a 2d array passed to a function?
Question
Why does the following code give me a segmentation fault?
#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);
}
It seems to be that the scanf
and printf
statements aren't getting the right data type passed in, but I can't work out what they should be.
How can I change it so that it works properly?
Solution
This declares an array of MAXROWS
arrays of pointers to int
.
int *data[MAXROWS][MAXCOLS];
However, in a function definition, top level arrays (of any size) are equivalent to pointers because arrays always decay to pointers to the type of the array member on passing to a function.
So your function definition is equivalent to:
void getInput (int *(*data)[MAXCOLS])
i.e. a pointer to an array of MAXCOLS
pointers to int
.
As your code stands, you never initialize any of the int
pointers in the array, as you are passing a 2d array of int
s as a pointer to a 2d array of int *
.
What you probably want to pass, is a pointer to an array of MAXCOLS
int
:
void getInput (int (*data)[MAXCOLS])
or equivalently:
void getInput (int data[][MAXCOLS])
Then you do the following:
int main(void)
{
int data[MAXROWS][MAXCOLS];
getInput(data);
return 0;
}
You are then passing your 2d array as a pointer to its first element (a pointer to a row or an array of MAXCOLS
int
s).
If you make sure change be sure to change:
scanf ("%d", data[curRow][curCol]);
printf ("%d\n", *data[curRow][curCol]);
to:
scanf ("%d", &data[curRow][curCol]);
printf ("%d\n", data[curRow][curCol]);
Also, check your parameters here:
scanf ("%d %d", &rows, &cols);
You need to be passing pointers to rows
and cols
.
Make sure to add some bounds checking to your input function so that you don't attempt to read more rows and columns than MAXROWS
or MAXCOLS
.
OTHER TIPS
scanf accepts address of variables, not the content of it:
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]);
}
}
}
There were a few different problems.
First, when passing arrays to functions you only need the definition of N-1 dimensions. For example if you're passing a 3D array you would put the size of the last 2 dimensions in the function sig and leave the first one empty.
foo(int threeD[][10][15]);
Second, scanf takes the address of the argument, which for your array looks like this
&data[curRow][curCol]
Third, you should always check the range of you input to make sure it's valid:
if (rows > MAXROWS || cols > MAXCOLS) {
printf("Bad array dimensions\n");
return;
}
Fourth, always compile with all warnings turned on - the compiler will warn you about allot of these things:
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;
}