2

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?

3
  • 1
    Are you malloc-ing p? Your immediate problem looks like a null pointer issue. Commented Sep 13, 2016 at 16:15
  • 2
    You need to initialize p to point to something valid - a local or global struct list object or dynamically allocated memory (such as through malloc()). As your code stands, p points to nothing valid - it is uninitialized. Commented Sep 13, 2016 at 16:18
  • 1
    It is imperative that you set up your compiler to produce most possible warnings and treat them as errors. If you are using common command line tools, add at least -Wall -Werror to the compilation command. If you are using an IDE, I dunno, fiddle with the menus maybe. Commented Sep 13, 2016 at 16:20

3 Answers 3

1

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);
}
Sign up to request clarification or add additional context in comments.

1 Comment

thank you so much! I forgot the basic principle when initiating a pointer...I should always remember to make a new pointer point to something. thanks again!!
1

Here is the C version of sandipan's answer, since that is in C++ and you tagged it C.

List *p = malloc(sizeof(List));
if(!p)
{
   //memory allocation failed, handle error here
}
scanf("%s", p->name); 
printf("%s\n", p->name);
//do stuff
free(p); //don't leak memory!

3 Comments

Thanks @PaulR, I've been using a really old code base in C at work lately and I've gotten used to seeing casts with malloc everywhere.
thank you so much! ! it's a really careless mistake which could be made by beginners like me....
@Zachary Happy to help. If this answers your question, click the checkmark next to the answer to close the question.
-1

You need to allocate memory to the pointer (from the heap) in the second case for it to work (and delete the memory allocated to the pointer, when done, to prevent memory leakage). In the first case, the local variable gets created on the stack. Here is the C++ version:

typedef struct list{ char name[10]; } List; 
List *p = new List; 
scanf("%s", p->name); 
printf("%s\n", p->name);
delete p;

Here is the C version:

typedef struct slist{ char name[10]; } SList; 
SList *p1 = (SList*)malloc(sizeof(SList)); 
scanf("%s", p1->name); 
printf("%s\n", p1->name);
free(p1);

1 Comment

You should use malloc/free instead of new/delete, this question is tagged C not C++

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.