2

Ok, so I have a 2D Array that is initialised with values from a file (format: x y z).
My file reads in the values correctly but when adding the z value to the matrix/2DArray, I run into a segfault and I have no idea why. It is possibly incorrect use of pointers? I still don't quite have the hang of them yet.

This is my initialiser, works fine, even initialises all "z" values to 0.

int** make2DArray(int rows, int columns)
{
    int** newArray;
    newArray = (int**)malloc(rows*sizeof(int*));
    if (newArray == NULL)
    {
        printf("out of memory for newArray.\n");
    }
    for (int i = 0; i < rows; i++)
    {
        newArray[i] = (int*)malloc(columns*sizeof(int));
        if (newArray[i] == NULL)
        {
            printf("out of memory for newArray[%d].\n", i);
        }
    }

    //intialise all values to 0
    for (int i = 0; i < rows; i++)
    {
        for (int j = 0; j < columns; j++)
        {
            newArray[i][j] = 0;
        }
    }

    return newArray;
}

This is how I call the initialiser (and problem function).

int** map = make2DArray(rows, columns);
fillMatrix(&map, mapFile);

And this is the problem code.

void fillMatrix(int*** inMatrix, FILE* inFile)
{
    int x, y, z;
    char line[100];
    while(fgets(line, sizeof(line), inFile) != NULL)
 {
  sscanf(line, "%d %d %d", &x, &y, &z);
  *inMatrix[x][y] = z;
 }
}

From what I can gather through the use of ddd, the problem comes when y gets to 47.
The map file has a max "x" value of 47 and a max "y" value of 63, I'm pretty sure I haven't got the order mixed up, so I don't know why the program is segfault-ing? I'm sure it's some newbie mistake...

1
  • Building a matrix as an array of arrays will result in poor performance for three reasons. 1: Looking up an element requires two memory accesses (1 to get the row pointer, and then another one to look up the value in the row); 2: The matrix elements are not stored contiguously, which harms caching; and 3: It prevents you from using high-performance matrix libraries like BLAS. Commented Jul 29, 2017 at 10:08

1 Answer 1

3

The subscript has higher precedence than the dereference operator, so you need a pair of parentheses:

(*inMatrix)[x][y] = z;

However, with your use case, you could just pass the int** directly to fillMatrix; the extra indirection is unnecessary.

Sign up to request clarification or add additional context in comments.

3 Comments

adding the parentheses still gave a segfault, the specific line is the one we are refering to: *inMatrix[x][y] = z; however I can't understand why it adds fine all the way up to y= 46, then y=47 gives a segfault. Also note that the make2DArray and fillMatrix method are in a file called map.c while the call to them is from a different file.
@TeeJay: You need to be sure to test the return value of sscanf to ensure that it succeeded and you need to check the input values to be sure that they are within the bounds of the array (never, ever trust program input).
I believe my problem was in the malloc-ing of the matrix. I was looping through from i = 0 to i < rows, but then accessing up to rows, so I was access out of bounds.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.