1

I've to write a function in C which takes as input a filepointer and returns a structure like this:

typedef struct product{
    char * code_product;
    char * name;
    char * code_piece;
    only_time_t enter;
    only_time_t exit;
}product_t;

This struct uses another struct like this:

typedef struct only_time{
    int hour;
    int minute;
    int second;
}only_time_t;

In order to read from the file I use the getline() function and the I use the strtok() function to create tokens. Here is the function I use to read from the file:

product_t * read_line(FILE * fp){
    char * line = NULL;
    size_t len = 0;
    product_t * temp;
    int i = 0;

    temp = (product_t *) malloc(sizeof(product_t));

    temp->code_product = (char *) malloc(sizeof(char) * 4);
    temp->name = (char *) malloc(sizeof(char) * 60);
    temp->code_piece = (char *) malloc(sizeof(char) * 4);

    //read a line from the file
    getline(&line, &len, fp);

    //handle line info info
    char *tokens[80];

    tokens[0] = strtok(line," ,.");

    while (tokens[i] != NULL) {
        i++;
        tokens[i] = strtok(NULL," ,.");                             
    }

    temp->code_product = tokens[0];
    temp->name = tokens[1];
    temp->code_piece = tokens[2];
    temp->enter = timestring_to_time(tokens[3]);
    temp->exit = timestring_to_time(tokens[4]);

    //cleanup
    if (line)
        free(line);
    return(temp);
}

In order to see what the program has read I use a simple function which prints the struct:

void print_product(product_t * product){
    printf("product_t code_product: %s \n", product->code_product);
    printf("product_t name: %s \n", product->name);
    printf("product_t code_piece: %s \n", product->code_piece);
    printf("product_t enter: %d:%d:%d \n", product->enter.hour,product->enter.minute,product->enter.second);
    printf("product_t exit: %d:%d:%d \n", product->exit.hour,product->exit.minute,product->exit.second);
}

I have setup a testcase which has the following line in the text file (called test.txt and placed in the same folder as the executalble):

H235 Sportello_dx N246 15:20:43 15:27:55

However the output of the program is:

product_t code_product: ��)�� 
product_t name:  
product_t code_piece: N246 
product_t enter: 15:20:43 
product_t exit: 15:27:55 

here is a pastebin with the entire code ready to run: https://pastebin.com/9rz0vM5G

why am I getting this wierd output for the first 2 lines but the rest is working?

BRHSM
  • 854
  • 3
  • 13
  • 48
  • 1
    `malloc(sizeof(char) * 4)` is one too small for _string_ `"H235"`. `temp->code_product = tokens[0];` throws away the memory previously allocated. Research `strdup()`. – chux - Reinstate Monica Jun 05 '18 at 11:20

1 Answers1

1

strtok() modifies the string while it is parsed and returns pointers to inside that same string, in your case line. So when you later free(line) you free the memory the temp structure references. Research strdup().

Goswin von Brederlow
  • 11,875
  • 2
  • 24
  • 42
  • thank you, just remiving the `free()` function solved the problem. Is this a good practice though? – BRHSM Jun 05 '18 at 12:11
  • 1
    No. Without the free(line) you are leaking memory. As said research strdup() to copy the parts you need out of line so line can be freed. And don't forget to free the strings when you free temp. – Goswin von Brederlow Jun 05 '18 at 12:21