Arch
Arch

Reputation: 1

fscanf and linked list's char *

struct node {
        ...
        char *name;
        ...
        struct node *next;
};

in recursive function:

head->name = (char *) malloc(sizeof(char));
if (fscanf(fp, "id\t%d\nname\t%s\nmobile\t%lld\n", &head->id, head->name, &head->mobile) > 0) {
    printf("%s\n", head->name);

it stores correct data...suppose...

rutvik

abhinav

but when print data...

printf("%d\t%s\t%lld\n", head->id, head->name, head->mobile);

1 rutvik 9876655433

2 ��nav 1234567789


Let's put char pointer aside for a while. code works great with structure

struct node {
...
char name[10];
...
struct node *next;

};

but not when I take name [20], it affects long long mobile's value... why??

Output:

1 Rutvik 9876655433

2 Abhinav 578692242758466

578692242758466 is unexpected.

Upvotes: 0

Views: 643

Answers (2)

perreal
perreal

Reputation: 98088

This line:

head->name = (char *) malloc(sizeof(char));

Allocates only 1 byte memory. You need to determine a maximum size and allocate that much characters:

head->name = (char *) malloc(sizeof(char) * MAXNAME);

Then you might as well change the struct to:

struct node {
        ...
        char name[MAXNAME];
        ...
        struct node *next;
};

A better option is to keep the struct as is, have a MAXNAME size buffer to read from the file with scanf, then allocate sufficient space for the name:

// + 1 for the null character at the end
head->name = (char *) malloc(sizeof(char) * (strlen(buffer) + 1)); 

Upvotes: 2

Jonathan Leffler
Jonathan Leffler

Reputation: 754570

You allocate sizeof(char) bytes, which is one byte, big enough for a null byte at the end of the string. You read using %s which is unconstrained for length.

This is a heap buffer overflow; it usually leads to unhappiness. You need to decide how much data you are going to allocate (32, 64, 4096, some other number) of bytes, and then use a format string such as %31s or %63s or %4095s or whatever to read the data into it.

Don't forget to check that the allocation succeeded!

There are those who will castigate you for casting malloc(). If you compile with a mode such that undeclared functions are not accepted, then there's nothing much wrong with the cast in general.

Upvotes: 3

Related Questions