0

I'm trying to add an array called shape inside a struct but once I add it and try to access the member values, it produces a segmentation fault. If I remove it, the program works perfectly.

This is the struct definition:

struct coo_matrix{
    int nnz;
    int shape[2];
    int * rows;
    int * columns;
    int * values;
};
typedef struct coo_matrix * COOMatrix;

This is the function where I try to access values:

COOMatrix coo_matrix_create(int m, int sparse_matrix[][m]){
    ...
    COOMatrix coo;
    coo = malloc(sizeof(COOMatrix));
    coo->rows = malloc(n * m * sizeof(int));
    coo->columns = malloc(n * m * sizeof(int));
    coo->values = malloc(n * m * sizeof(int));
    ....
    ....
            coo->rows[k] = i;
            coo->columns[k] = j;
            coo->values[k] = sparse_matrix[i][j]; // see Note
    ....
    return coo;
}

Note: Once I add shape, this line produces a segmentation fault.

PS: No need to say I am not very familiar with C, I learned other languages before I ever touched C recently.

6
  • 1
    COOMatrix and coo_matrix are different things. you haven't shown any typedefs here. Commented May 14, 2017 at 18:10
  • @sjsam I forgot to include it in my question. Added Commented May 14, 2017 at 18:13
  • typdefing pointers is bound to get you into trouble. Commented May 14, 2017 at 18:15
  • @DavidBowling Any idea why this is happening? Commented May 14, 2017 at 18:19
  • Why are you using sizeof(COOMatrix) in all allocations? You need sizeof(struct coo_matrix), or better, sizeof *coo for the first allocation. Commented May 14, 2017 at 18:21

1 Answer 1

2

You have a couple of problems in that code. First, you declare your COOMatrix as a pointer but then confuse things by using it to get the size of the underlying struct. Secondly, you declare rows, columns and values as pointers to ints but then allocate them using sizeof(COOMatrix). Because of the first error, the second might actually work depending on the machine but isn't what you want. So

struct coo_matrix{
...
};
typedef struct coo_matrix COOMatrix;
COOMatrix *coo_matrix_create(int m, int sparse_matrix[][m]){
    ...
    COOMatrix *coo;
    coo = malloc(sizeof(COOMatrix));
    coo->rows = malloc(n * m * sizeof(int));
    coo->columns = malloc(n * m * sizeof(int));
    coo->values = malloc(n * m * sizeof(int));
    ....
    ....
            coo->rows[k] = i;
            coo->columns[k] = j;
            coo->values[k] = sparse_matrix[i][j]; // see Note
    ....
    return coo;
}

Should be closer

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

3 Comments

You are right about sizeof. It was a copy/paste mistake facepalm. I guess I should go to sleep for a while
Better to use malloc(sizeof(int) * n * m), or better yet, malloc(sizeof *coo->rows * n * m) to reduce risk of potential integer overflow problems, i.e., to ensure that math is done with size_t types.
@DavidBowling That is a really nice tip!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.