Zachary Zachary - 2 months ago 12
C Question

c- scanf a string into a struct by using a struct pointer

I am trying to read a string into a struct member via

scanf()
.
If I initiate a struct like this, it will compile and run just fine:

typedef struct list {
char name[10];
...
} List;

List p;
scanf("%s", p.name);
printf("%s\n", p.name);


If I initiate the struct by a pointer then it still compiles fine, but the resulting program crashes:

typedef struct list {

char name[10];
...
} List;

List *p;
scanf("%s", p->name);
printf("%s\n", p->name);


Why does that happen?

Answer

If you declare p as type struct list then memory for a struct list is allocated for it automatically. You can write into that memory and subsequently read back what you've written, as you do in the first example.

If you declare p as type struct list * then memory for a pointer is automatically allocated for it. There is no memory allocated for a struct list, in part because you might not actually want any -- you might want to assign your pointer to point to a struct list that was allocated by other means. You can write to the pointer and read back what you've written, but that's not what you're trying to do in your second code. You are trying to write to and read from the thing to which the pointer points, while the pointer's value is still indeterminate. This yields undefined behavior, of which a program crash is a fairly benign example.

If you want to use the pointer then you have two main alternatives:

  1. Point it to an existing struct list:
List list;
List *p = &list;

scanf("%s", p->name);
printf("%s\n", p->name);
  1. Allocate memory dynamically for a struct list, and free it when you're done:
List *p = malloc(sizeof *p);

if (!p) {
    // handle allocation failure
} else {
    scanf("%s", p->name);
    printf("%s\n", p->name);
    free(p);
}