Search code examples
carrayseclipseeclipse-cdt

Eclipse terminating without message during assignment of 2D-Array element


I'm experiencing odd behavior in Eclipse / C. I have the following type declared in, lets say, a.h.

typedef double sig_type[3];

and the following in, lets say, b.c

typedef struct filter_kind {
. . . 
sig_type *     fil_buff;         //The buffer for all values
. . .
} filter_kind;


 int init_filter(filter_kind * filter, const sig_type init_data[],
            const int data_len) {

    if (filter->data_buff_len != data_len) {
        return -1
    }

    int i;
    int j;
    for (i = 0; i < filter->data_buff_len; i++) {
        for (j = 0; j < OUT_NUM; j++) {
            (filter->fil_buff)[i][j] = init_data[i][j];   //prog exits on this line.
        }
    }

    filt_coeffs(filter);

    return 0;
}

I have a specified function to return a pointer to a malloced filter_kind structure, which mallocs fil_buff. When I use this creation function, and pass the newly created filter_kind pointer to init_filter, the function unexpectedly exits when assigning to (filter->fil_buff)[][] -- with almost no note other than "gdb" in the Debug view.

I've dropped in some probe variables, and viewed them during debug, and nothing seems abnormal up until this point. I can read from the array fine, just cannot assign. Am I doing something wrong here?

And lastly, here is the constructor function with corresponding allocation functions.

filter_kind * create_filter(const double f_lo, const double f_hi,
        const double samp_r, win_type window_t, fil_type filter_t,
        const int buff_len) {

    filter_kind * filter;
    sig_type * fil_buff;
    int err = 0;

    /* allocate filter struct */
    filter = (filter_kind *) malloc(sizeof(filter_kind));

    err = (filter != NULL ) ? 0 : -1;
    if (err == -1) {
        return NULL ;
    }
    memset(filter, 0, sizeof(filter_kind));

    /* allocate filter data members */
    err = alloc_buffs(win_coeffs, fil_coeffs, fil_buff, buff_len);
    if (err == -1) {
        return NULL ;
    }

    //assign other structure values...
    filter->fil_buff = fil_buff;


    return filter;
}


static int alloc_buffs(double * win_coeffs, double * fil_coeffs,
        sig_type * fil_buff, const int buff_len) {
    int err = 0;

//allocate other buffers...
    err = alloc_st_buff(fil_buff, buff_len);
    if (err == -1) {
        return -1;
    }

    return 0;
}

static int alloc_st_buff(sig_type * st_buff, const int buff_len) {
    const int num_bytes = sizeof(sig_type) * buff_len;

    st_buff = (sig_type *) malloc(num_bytes);
    const int err = (st_buff != NULL ) ? 0 : -1;

    if (err == -1) {
        return -1;
    }

    memset(st_buff, 0, num_bytes);
    return 0;
}

and for what it's worth, designed to be used as follows

filter_kind * filter;
filter = create_filter(...);

/* Load data into array of sig_type, i.e. sig_type arr[40] */

init_filter(filter, arr, 40);

/* more code... */

Solution

  • Ok problem is with allocating buffers (calling allocating function):

    sig_type * fil_buff;
    err = alloc_buffs(win_coeffs, fil_coeffs, fil_buff, buff_len);
    filter->fil_buff = fil_buff;
    

    So what is happening here:

    • Create pointer to a table called fil_buff,
    • call function alloc_buffs with copies of pointers to fil_buff etc.,
    • assign not changed fil_buff to a structure.

    Every time function takes argument it makes a copy of it. So when you passed a pointer, then function made a copy of this pointer (and it was operating on a copy of the pointer), thus original pointer (before function call) is not changed. You should pass pointer to the pointer you want to operate on. The way it could be done is:

    err = alloc_buffs(win_coeffs, fil_coeffs, &fil_buff, buff_len);
                                              ^^^^^^^^^
    

    then your fil_buff can really be changed, but you have to adjust your function to take proper arguments and to properly operate on them. I guess the same mistake has been made with other buffers.