Santiago Aguilar
Santiago Aguilar

Reputation: 15

Why I am having a Segmentation fault?

/* This Program generates a file with a pseudo-random number of st_record_t structures. The file is passed by command line arguments. The program must by executed, in UNIX, this way: ./file_gen -path <path> */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "types.h"

#define MSG_INVALID_INPUT "Your input was not valid"

#define CMD_FLAG_PATH_POSITION 1 
#define CMD_ARG_PATH_POSITION 2

#define CMD_FLAG_PATH "-path"

#define SDM_MAX 10000.0

status_t validate_arguments (int argc, char * argv []);

int main (int argc, char * argv [])
{
    FILE * fi;
    size_t i;
    st_record_t aux_struct, aux2_struct;
    int size;

    if ((validate_arguments(argc, argv))!= OK)
    {
        fprintf(stderr, "%s\n", MSG_INVALID_INPUT);
        return EXIT_FAILURE;
    }

    if((fi = fopen(argv[CMD_ARG_PATH_POSITION], "wb")) == NULL)
        return EXIT_FAILURE;

    srand(time(NULL));
    for (i=0; i<(size=100); i++)
    {
        aux_struct.SDM = (((float)rand()/(float)(RAND_MAX)) * SDM_MAX); /*pseudo-random real number between 0 and SDM_MAX*/
        (aux_struct.ID) = i;
        (aux_struct.coordinates)->latitude.deg = rand()%180;
        (aux_struct.coordinates)->latitude.min = rand()%60; 
        (aux_struct.coordinates)->latitude.sec = rand()%60;
        (aux_struct.coordinates)->longitude.deg = rand()%180;
        (aux_struct.coordinates)->longitude.min = rand()%60;
        (aux_struct.coordinates)->longitude.sec = rand()%60;
        if((fwrite (&aux_struct, sizeof(st_record_t), 1, fi))!=1)
            return ERROR_WRITING_FILE;
      }

    if(fclose(fi) == EOF)
        return EXIT_FAILURE

    return EXIT_SUCCESS;
}

The problem is with the (aux_struct.coordinates)->latitude.deg = rand()%180 lines. If instead of using a random number I select one, this won't happen

The st_record_t struct is defined this way:

typedef struct {
        unsigned char deg, min, sec;
        }angle_t;

typedef struct {
        angle_t latitude, longitude;
        }st_coord_t;

typedef struct {
        float SDM;
        size_t ID;
        st_coord_t * coordinates;
        }st_record_t;

Upvotes: 0

Views: 78

Answers (3)

maartenb64
maartenb64

Reputation: 33

In addition to the issue of the missing initialization of the "coordinates" member, it should be pointed out that the fwrite() will not do what you want. It will just write the contents of the st_record_t. The value of the pointer "coordinates" has no meaning outside the process that is doing the writing and the data in the st_coord_t structure it points to will not get written at all.

You might want to look at something like hdf5 to write complex binary data structures to file in a portable way.

Upvotes: 1

Spikatrix
Spikatrix

Reputation: 20244

You have

typedef struct {
        float SDM;
        size_t ID;
        st_coord_t * coordinates;
        }st_record_t;

As you can see,coordinates is a pointer of type st_coord_t. You need to allocate memory for it using malloc:

aux_struct.coordinates=malloc(sizeof(st_coord_t));

And you need to free the allocated memory after its use using:

free(aux_struct.coordinates);

Note that you must allocate memory for coordinates in aux2_struct if you want to use it and later free it after its use.

Upvotes: 0

Yu Hao
Yu Hao

Reputation: 122363

The segmentation fault has nothing to do with random number, it's because you never allocate memory for aux_struct.coordinates.

To fix the problem, use something like:

aux_struct.coordinates = malloc(sizeof(st_coord_t));

Remember to free the memory when it's not used any more.

Upvotes: 1

Related Questions