egarciab
egarciab

Reputation: 41

Segmentation fault when changing value but not when printing

In the following code, I initialize a struct array that is inside another struct. After initializing the array, I can print all the values without problem in loop #1.

However, if I try to change the values, as in Loop #2, I get a segmentation fault when when trying to access the element exactly at the middle of the array (i.e. when j==points/2, or 50 in this particular case).

Why is it that accessing the element to print it works but trying to change it causes a segmentation fault?

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

struct flux{
  double *intense;
  double *tau;
};

struct radius_struct{
  int id;
  struct flux *flux;
};

int main(int argc, const char * argv[]) {
    
    int i,j, ichan, points,nchan;
    points = 100;
    nchan = 20;
    
    struct radius_struct radius_struct;
    radius_struct.id = 99;
    radius_struct.flux = malloc(sizeof(double) * points);
    
    
    for(i = 0; i < points; i++){
      radius_struct.flux[i].intense= malloc(sizeof(double) * nchan);
      radius_struct.flux[i].tau= malloc(sizeof(double) * nchan);

      for(ichan=0;ichan<nchan;ichan++){
        radius_struct.flux[i].intense[ichan] = ichan;
        radius_struct.flux[i].tau[ichan] =ichan;
      }
    }
    
    //Loop #1
    for(j = 0; j < points; j++){
      for(ichan=0; ichan<nchan; ichan++){
         printf("%f %f\n", radius_struct.flux[j].intense[ichan],  radius_struct.flux[j].tau[ichan]);
      }
    }
    
    //Loop #2
    for(j = 0; j < points; j++){
      for(ichan=0; ichan<nchan; ichan++){
          radius_struct.flux[j].intense[ichan] = 123.456;
          radius_struct.flux[j].tau[ichan] = 123.456;
      }
    }

    return 0;
}

Upvotes: 4

Views: 109

Answers (2)

chux
chux

Reputation: 154075

Avoid allocation sizing errors.

Allocate to the size of the referenced object. Easier to code right, review and maintain.

//                             v------------v wrong size 
// radius_struct.flux = malloc(sizeof(double) * points);
radius_struct.flux = malloc(sizeof *(radius_struct.flux) * points);
//                          ^--------------------------^ right size, even without looking up .flux type.

why doesn't it fail when accessing them in the initialization or when printing them before Loop #2? –

radius_struct.flux[i].intense and all following code is suspect and subject to undefined behavior as the prior allocation was not certainly sufficient. Some things might work, others might not. See also @CiaPan.


Robust code would also check the return pointer for allocation failure with a check against NULL.

Upvotes: 3

Wael ben hassen
Wael ben hassen

Reputation: 1

as pointed out in the comment, radius_struct.flux is of type "struct flux". so all you have to do is replace

radius_struct.flux = malloc(sizeof(double) * points);

with

radius_struct.flux = malloc(sizeof(struct flux) * points);

Upvotes: 0

Related Questions