1

I'm trying to store large csv file into an dynamically allocated array of structs in C language and I do not know why but I keep getting segment default after 5 rows in the file. I'm using gcc to compile and cat [NameOfFile].csv|... to include csv file into standard input. So my struct is:

typedef struct{
    int num_critic_for_reviews;
    int duration;
    int director_facebook_likes; 
    int actor_3_facebook_likes; 
    int actor_1_facebook_likes; 
    int gross; 
    int num_voted_users; 
    int cast_total_facebook_likes;
    int facenumber_in_poster;
    int budget; 
    int title_year; 
    int actor_2_facebook_likes; 
    int imdb_score; 
    int aspect_ratio; 
    int movie_facebook_likes;    
    int num_user_for_reviews;
    char* color;
    char* director_name;
    char* actor_2_name;  
    char* genres; 
    char* actor_1_name; 
    char* movie_title;  
    char* actor_3_name; 
    char* plot_keywords; 
    char* movie_imdb_link;
    char* language; 
    char* country; 
    char* content_rating;        
}csvfile;
typedef csvfile CSVFILE;

I declared:

CSVFILE data[MAX_ROW]; //MAX_ROW = 1000;

and allocated the memory inside data:

CSVFILE* data = (CSVFILE*) malloc((MAX_ROW * sizeof(csvfile)));

I think there is something wrong with how I allocated the memory inside the data but I am so sure where. After this, I used fgets() in a while loop to read the file and store the value in the members of struct when it goes through each row and also I reallocated the memory when it reaches the MAX_ROW.

2
  • You used the same name for an array and a pointer? Commented Sep 28, 2017 at 19:49
  • Are you allocating space for all the pointers inside the struct, like color, director_name, etc. Commented Sep 28, 2017 at 20:13

2 Answers 2

1

Here is an example illustrating how to read all records from a CSV file into a dynamically allocated struct:

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

#define LINE_MAX_LEN            (1024 * 4)   /* 4 KBytes */

struct record_s
{
    int num_critic_for_reviews;
    int duration;
    int director_facebook_likes;
    int actor_3_facebook_likes;
    int actor_1_facebook_likes;
    int gross;
    int num_voted_users;
    int cast_total_facebook_likes;
    int facenumber_in_poster;
    int budget;
    int title_year;
    int actor_2_facebook_likes;
    int imdb_score;
    int aspect_ratio;
    int movie_facebook_likes;
    int num_user_for_reviews;
    char* color;
    char* director_name;
    char* actor_2_name;
    char* genres;
    char* actor_1_name;
    char* movie_title;
    char* actor_3_name;
    char* plot_keywords;
    char* movie_imdb_link;
    char* language;
    char* country;
    char* content_rating;
};

typedef struct record_s record_t;


char ** strsplit( const char * src, const char * delim )
{
    char * pbuf = NULL;
    char * ptok = NULL;
    int count = 0;
    int srclen = 0;
    char ** pparr = NULL;

    srclen = strlen( src );

    pbuf = (char*) malloc( srclen + 1 );

    if( !pbuf )
        return NULL;

    strcpy( pbuf, src );

    ptok = strtok( pbuf, delim );

    while( ptok )
    {
        pparr = (char**) realloc( pparr, (count+1) * sizeof(char*) );
        *(pparr + count) = strdup(ptok);

        count++;
        ptok = strtok( NULL, delim );
    }

    pparr = (char**) realloc( pparr, (count+1) * sizeof(char*) );
    *(pparr + count) = NULL;

    free(pbuf);

    return pparr;
}


void strsplitfree( char ** strlist )
{
    int i = 0;

    while( strlist[i])
        free( strlist[i++] );

    free( strlist );
}


record_t * parse_record( char * line )
{
    char ** pp = NULL;
    record_t * rec = NULL;

    pp = strsplit( line, ";" );

    rec = (record_t*) calloc( 1, sizeof(record_t) );

    rec->num_critic_for_reviews = atoi(pp[0]);
    rec->duration = atoi(pp[1]);
    rec->director_facebook_likes = atoi(pp[2]);
    rec->actor_3_facebook_likes = atoi(pp[3]);
    rec->actor_1_facebook_likes = atoi(pp[4]);
    rec->gross = atoi(pp[5]);
    rec->num_voted_users = atoi(pp[6]);
    rec->cast_total_facebook_likes = atoi(pp[7]);
    rec->facenumber_in_poster = atoi(pp[8]);
    rec->budget = atoi(pp[9]);
    rec->title_year = atoi(pp[10]);
    rec->actor_2_facebook_likes = atoi(pp[11]);
    rec->imdb_score = atoi(pp[12]);
    rec->aspect_ratio = atoi(pp[13]);
    rec->movie_facebook_likes = atoi(pp[14]);
    rec->num_user_for_reviews = atoi(pp[15]);
    rec->color = strdup(pp[16]);
    rec->director_name = strdup(pp[17]);
    rec->actor_2_name = strdup(pp[18]);
    rec->genres = strdup(pp[19]);
    rec->actor_1_name = strdup(pp[20]);
    rec->movie_title = strdup(pp[21]);
    rec->actor_3_name = strdup(pp[22]);
    rec->plot_keywords = strdup(pp[23]);
    rec->movie_imdb_link = strdup(pp[24]);
    rec->language = strdup(pp[25]);
    rec->country = strdup(pp[26]);
    rec->content_rating = strdup(pp[27]);

    strsplitfree( pp );

    return rec;
}


void destroy_record( record_t * rec )
{
    free(rec->color);
    free(rec->director_name);
    free(rec->actor_2_name);
    free(rec->genres);
    free(rec->actor_1_name);
    free(rec->movie_title);
    free(rec->actor_3_name);
    free(rec->plot_keywords);
    free(rec->movie_imdb_link);
    free(rec->language);
    free(rec->country);
    free(rec->content_rating);
    free(rec);
}


void show_record( record_t * rec )
{
    printf( "[ RECORD ]\n" );
    printf( "   num_critic_for_reviews: %d\n", rec->num_critic_for_reviews );
    printf( "   duration: %d\n", rec->duration );
    printf( "   director_facebook_likes: %d\n", rec->director_facebook_likes );
    printf( "   actor_3_facebook_likes: %d\n", rec->actor_3_facebook_likes );
    printf( "   actor_1_facebook_likes: %d\n", rec->actor_1_facebook_likes );
    printf( "   gross: %d\n", rec->gross );
    printf( "   num_voted_users: %d\n", rec->num_voted_users );
    printf( "   cast_total_facebook_likes: %d\n", rec->cast_total_facebook_likes );
    printf( "   facenumber_in_poster: %d\n", rec->facenumber_in_poster );
    printf( "   budget: %d\n", rec->budget );
    printf( "   title_year: %d\n", rec->title_year );
    printf( "   actor_2_facebook_likes: %d\n", rec->actor_2_facebook_likes );
    printf( "   imdb_score: %d\n", rec->imdb_score );
    printf( "   aspect_ratio: %d\n", rec->aspect_ratio );
    printf( "   movie_facebook_likes: %d\n", rec->movie_facebook_likes );
    printf( "   num_user_for_reviews: %d\n", rec->num_user_for_reviews );
    printf( "   color: %s\n", rec->color );
    printf( "   director_name: %s\n", rec->director_name );
    printf( "   actor_2_name: %s\n", rec->actor_2_name );
    printf( "   genres: %s\n", rec->genres );
    printf( "   actor_1_name: %s\n", rec->actor_1_name );
    printf( "   movie_title: %s\n", rec->movie_title );
    printf( "   actor_3_name: %s\n", rec->actor_3_name );
    printf( "   plot_keywords: %s\n", rec->plot_keywords );
    printf( "   movie_imdb_link: %s\n", rec->movie_imdb_link );
    printf( "   language: %s\n", rec->language );
    printf( "   country: %s\n", rec->country );
    printf( "   content_rating: %s\n", rec->content_rating );
    printf( "\n" );
}


int main( int argc, char * argv[] )
{
    char line[ LINE_MAX_LEN + 1 ];
    record_t * r = NULL;
    FILE * fp = NULL;

    fp = fopen( argv[1], "r" );

    while( fgets( line, LINE_MAX_LEN, fp ) )
    {
        r = parse_record( line );
        show_record( r );
        destroy_record( r );
    }

    fclose(fp);

    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

0

The problem is, I think, that you haven't allocated the char *s in your struct.

When you have a struct with pointers in it, a simple malloc(sizeof(struct name)); will allocate only the space required for each variable, which in case of pointers is only the space to store the pointer address. This means that your char * pointers will point to some place in memory that is not allocated.

A solution could be to allocate the struct and then allocate other memory for every pointer in the struct. But if you know how much space will need every string in your struct you could simply substitute every char *variable with char variable[SIZE]. This way sizeof(struct name) will allocate the right space and you will not need to allocate every string after.

Comments

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.