1

I am trying to learn struct in C. The code complies fine, when I try to input a value, it crashes. I tried with an int member and it works.

typedef struct node{
    char *productName;
    int price;
    struct node *next;

}node;

int main (){
    node *head = (node*) malloc(sizeof(node));
    printf("Enter a product name: ");
    scanf("%s", &head->productName);
    printf("Product entered:%s",head->productName);
    //scanf("%d", &head->price); // this works
    //printf("Price entered:%d",head->price);

}
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Gavin
  • 2,784
  • 6
  • 41
  • 78
  • [Please see this discussion on why not to cast the return value of `malloc()` and family in `C`.](http://stackoverflow.com/q/605845/2173917). – Sourav Ghosh Dec 27 '16 at 04:32
  • 1. Do not cast malloc - see [here](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). 2. What is `prodeuctName` pointing to? – Ed Heal Dec 27 '16 at 04:33
  • productName doesn't have memory allocated to keep whatever you are getting in scanf(). – Shivendra Mishra Dec 27 '16 at 04:35

3 Answers3

2

The first problem, %s with scanf() expects a char * argument, what you're passing is a char **.

That said, even after correcting that (removing the &), head->productName is uninitialized and it does not point to a valid memory location. Accessing uninitilized memory invokes undefined behavior.

You need to make the pointer point to a valid memory before you can read from or write into it.

Finally, you should always check for the success of malloc() before using the returned pointer.

Combining all of them, something like

node *head = malloc(sizeof *head);
if (head) {
    head->productName = malloc(32); //some arbitary size
    if (head->productName) {
        printf("Enter a product name: ");
        scanf("%31s", head->productName);
        printf("Product entered:%s",head->productName);
    }
}

should do the job.


Note: A generic advice, don't forget to free() the returned pointer by memory allocator functions to avoid any possible memory leak, as your code grows bigger.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
1

Probably, You need to write it something like this:

/*Following code is not tested - Just a sample*/
typedef struct node{
    char *productName;
    int price;
    struct node *next;
}node;

int main (){
    node *head = (node*) malloc(sizeof(node));
    if( head == NULL ) 
     /*fail*/
    printf( "Size of product name:");
    scanf( "%d",&size);
    head->productName = malloc(size);
    if( head->productName == NULL ) {
       /*fail*/
    }
    printf("Enter a product name: ");
    scanf("%s", head->productName);
    printf("Product entered:%s",head->productName);
    /*scanf("%d", &head->price); // this works
      printf("Price entered:%d",head->price);*/

    /*Do stuff with node here*/
    free(head->productName);
    free(head);
    return 0;
}
Shivendra Mishra
  • 638
  • 4
  • 25
  • `if( head->productName == NULL ) { /*fail*/ }.... scanf("%s", head->productName);`.. whole `if` thing is useless then. Assuming you're trying to write a MCVE. – Sourav Ghosh Dec 27 '16 at 04:52
0

Try this

scanf("%ms", &head->productName);

see how-can-i-read-an-input-string-of-unknown-length

may be this what you are looking for.

Community
  • 1
  • 1
Yogesh
  • 15
  • 6