1
typedef struct inventory 
{
   char *name; 
   int quantity; 
   double price; 
   struct inventory* next_inventory; 
   
} invent;

int main(void)
{
   invent *one=malloc(sizeof(invent)); 
   invent *two=malloc(sizeof(invent));
   invent *three=malloc(sizeof(invent));

   one->next_inventory=two;
   two->next_inventory=three;
   three->next_inventory=NULL;

   one->name=malloc(256);
   ...(repeat two->name, three->name)
   
   printf("name: ");
   scanf("%s", one->name);

   printf("qunatity: ");
   scanf("%d", &one->quantity);

   printf("price: ");
   scanf("%lf", &one->price);
   
   ...(repeat scanf() for two, three)

   while(one!=NULL)
   {
      printf("%s %d %.0f\n", one->name, one->quantity, one->price);
      printf("check\n");
      one=one->next_inventory;
   }

   free(one->name);
   free(two->name);
   free(three->name);
   free(one);
   free(two);
   free(three);

   return 0;

free(one->name); doesn't work. I checked another free(), using printf("check");, two->name, three->name, one ... its worked. Why only free(one->name) doesn't work? What can I do for solve this problem? Give me the advice.

  • `free(one->name); doesn't work` What do you mean by "doesn't work"? How _exactly_ do you see that that statement "doesn't work"? – KamilCuk Jun 26 '20 at 10:50
  • 3
    Well `one` is NULL at that point. I know it's NULL because if it wasn't NULL then the loop would've kept looping. – user253751 Jun 26 '20 at 10:51
  • 1
    @KamilCuk Segmentation fault: 11. And program is shut down. – erehwyrevemai Jun 26 '20 at 10:54
  • @user253751 Then what can I do for this problem? I should return the memory I used.(using malloc) – erehwyrevemai Jun 26 '20 at 10:58
  • try using a temporary variable to iterate. – farbiondriven Jun 26 '20 at 10:59
  • @erehwyrevemai Why would you want to `free()` a NULL pointer? – RobertS supports Monica Cellio Jun 26 '20 at 11:02
  • @RobertSsupportsMonicaCellio one->name and one is only NULL pointer? or is there another NULL pointer? – erehwyrevemai Jun 26 '20 at 11:13
  • You could not set one to NULL. Use a different variable for the loop. – user253751 Jun 26 '20 at 11:19
  • @user253751 I can't use a different variable. Because "There are only `one, two, three pointer` to point to struct." It's condition to my homework. – erehwyrevemai Jun 26 '20 at 11:39
  • @user3121023 It's work!!! Thank you very much...really really thank you...user 3121023!!!!! – erehwyrevemai Jun 26 '20 at 11:49
  • 1
    what if you have 100 elements in the inventory ? you go on doing one->next_inventory->next_inventory...100times...->name ? – farbiondriven Jun 26 '20 at 11:52
  • @farbiondriven If I have 100 elements in the inventory, of course I using loop(one=one->next_inventory). But In this homework , I can't use temporary pointer(condition), and there is only three struct(one, two, three, it's also condition). So In this case, `one->next_inventory->next_inventory->name` was the best way. If my homework wasn't conditional, I would have followed your advice! I really appreciate your comment! – erehwyrevemai Jun 26 '20 at 12:00
  • @user3121023 It's good way, but it doesn't match the conditions. I choice `one->next_inventory->next_inventory->name`. Thanks! – erehwyrevemai Jun 26 '20 at 12:16

2 Answers2

2

You are using your actual 'one' variable to do the iteration, in the end you are trying to free(one) where one points to NULL.

You should not lose track of the address of the memory you requested to allocate, to be able to release that memory later with free.

I would use a temporary pointer to iterate:

 invent* tmp = one;
 while(tmp!=NULL)
   {
      printf("%s %d %.0f\n", tmp->name, tmp->quantity, tmp->price);
      printf("check\n");
      tmp=tmp->next_inventory;
   }

// free all names and one, two, three.

In alternative:

you can define a function for printing:

void printAll(invent* one)
{
    while(one!=NULL)
   {
      printf("%s %d %.0f\n", one->name, one->quantity, one->price);
      one=one->next_inventory;
   }
}

then in the main, call

printAll(one)

This works as the pointer is passed by value in the function and you won't lose the original address.

farbiondriven
  • 2,450
  • 2
  • 15
  • 31
  • It's my homework, so it has conditions. Struct must have char *name, don't make struct without struct one, two, three, only using struct one for print. I appreciate your advice, But I can't using temporary pointer. – erehwyrevemai Jun 26 '20 at 11:10
  • you can't iterate using `one`, because how would you know after you are done with the printing where `one` was originally pointing to ? – farbiondriven Jun 26 '20 at 11:13
  • My professor said "There are only `one, two, three pointer` to point to struct. So I can't use `temporary pointer`. What should I do? – erehwyrevemai Jun 26 '20 at 11:38
1

Here is a improved version of your program that includes also checking malloc return code:

#include <stdlib.h>
#include <stdio.h>

typedef struct invent 
{
   char *name; 
   int quantity; 
   double price; 
   struct invent* next_inventory; 
   
} invent;

void enter(invent **s)
{
   printf("name: ");
   scanf("%s", (*s)->name);

   printf("quantity: ");
   scanf("%d", &(*s)->quantity);

   printf("price: ");
   scanf("%lf", &(*s)->price);
   
}

void *alloc(size_t size)
{
    void *p;
    
    p = malloc(size);
    if (p == NULL)
    {
        perror("malloc");
        exit(1);
    }
    return p;
}

int main(void)
{
   invent *start;

   invent *one;
   invent *two;
   invent  *three;

   one = alloc(sizeof(invent)); 
   two = alloc(sizeof(invent));
   three = alloc(sizeof(invent));

   start = one;

   one->next_inventory=two;
   two->next_inventory=three;
   three->next_inventory=NULL;

   one->name=alloc(256);
   two->name=alloc(256);
   three->name=alloc(256);


   enter(&one);
   enter(&two);
   enter(&three);

   while(one != NULL)
   {
      printf("%s %d %.0f\n", one->name, one->quantity, one->price);
      printf("check\n");
      one=one->next_inventory;
   }

   free(start->name);
   free(two->name);
   free(three->name);
   free(start);
   free(two);
   free(three);

   return 0;

}
pifor
  • 7,419
  • 2
  • 8
  • 16
  • I appreciate your advice, pifor. But my professor said "There are only `one, two, three pointer` to point to struct. What should I do without using `start`? – erehwyrevemai Jun 26 '20 at 11:36
  • 1
    Please give *all* specifications that you have: do you really need to have a loop to print data ? Do you really need to free memory ? Is C structure mandatory ? Can we modify this structure ? etc. This homework looks a little bit too artificial ... – pifor Jun 26 '20 at 11:48
  • I solved problem. Thank you pifor!!! When I think about it, I don't need to have a loop to print data. – erehwyrevemai Jun 26 '20 at 11:50