views:

90

answers:

4

Why do I get segmentation fault in this function:

#include <stdio.h>
#include <stdlib.h>
#include "math.h"

vec_t mtrx_multiple (sparse_mat_t a, vec_t c) {

    vec_t result;
    int i;

    result.n = a.n;
    printf("result.n: %d\n", result.n);


    result.vec = malloc(a.n * sizeof *result.vec);
    for(i=0; i<a.n; i++) 
        result.vec[i] = c.vec[i] * a.a[a.ja[i]];


    return result;
}

The structure is:

typedef struct {
    int n;
    int *vec;
} vec_t;

typedef struct {
    int *a;
    int *ia;
    int *ja;
    int n;
} sparse_mat_t;

Thanks for help

+2  A: 

I suspect the problem is with a.a[a.ja[i]], you should try verifying the values a.ja[i] before using them to index a.a.

It would be useful to know how a is initialised, and also on which line the segfault occurs.

Autopulated
the problem was that a didn't have a.n elements...
Devel
A: 

I suspect this is the line where the trouble is:

    result.vec = malloc(a.n * sizeof *result.vec);
    for(i=0; i<a.n; i++) 
        result.vec[i] = c.vec[i] * a.a[a.ja[i]];

The reason is that you are not mallocing for each result.vec[i]..

Can you confirm this?

Edit: Thanks Alok and Devel for informing me about my error... What does sizeof *result.vec return? Admittedly it looks confusing as if the precedence between sizeof gets mixed with the *...

Hope this helps, Best regards, Tom.

tommieb75
The `malloc` is doing just that, allocating space for `a.n` `int` values.
Alok
`a.n` is a number of the elements, so, as far as I understand malloc, this is supposed to malloc memory for all `a.n` newly created elements. There can't be more elements becouse of the `for(i=0; i<a.n; i++)`.
Devel
@Alok: Whoops! My bad... :( Thanks Devel.
tommieb75
It's okay, we've all made stupid mistakes before!
Alok
Regarding the sizeof *result.vec thing, I tested that line in my code :) it returns 4, or in my case the whole expression returned 20 when result.n was 5.
Justin Smith
but the funny thing is that he is getting the size of a pointer to a result.vec, when he should be getting the size of an int, the thing pointed at. Luckily for him, by coincidence, these two sizes are the same.
Justin Smith
@Justin, `sizeof *result.vec` is exactly equivalent to `sizeof(int)` in this case, because `result.vec` is of type `int *`. `sizeof` operator can be applied on an object or a type. In fact, I recommend it being applied on the object for `malloc` calls: http://stackoverflow.com/questions/2012473/reducing-stack-load-memory-allocation-in-c-and-easly-casting-mallocs-return-v/2012567#2012567
Alok
@Justin: so he is in fact calculating the proper size, not the size of `int *`.
Alok
*But to make an array of n objects you don't necessarily want to allocate space for n *pointers* to an object of that type. If it were an array of char, he would be allocating twice as much space as he needs, if it were an array of longs, it would be half as much.*Never mind, the above is wrong, I was confused.
Justin Smith
A: 

Malloc could be failing and returning null. a.ja[i] might not be between 0 and n. What is the ja array supposed to represent, anyway?

Our speculating isn't going to produce the answer. Running your program under a debugger will.

Keith Randall
A: 
Justin Smith