Search code examples
cmemory-managementdynamic-memory-allocationrealloc

c programming dynamic allocation of struct pointers


The program reads the input '1z' as (str+0)->input_name, '2y' as (str+1)->input_name, and '3x' as (str+2)->input_name. Now what i want to do is to insert a new string to (str+0)->input_name without eliminating the initial elements. So initial (str+0)->input_name would become (str+1)->input_name, (str+1)->input_name becomes (str+2)->input_name, and (str+2)->input_name becomes (str+3)->input_name. How would i do this??

Initialize items

Number of products: 3

Enter name: 1z

Enter name: 2y

Enter name: 3x

Output

1 -> 1z

2 -> 2y

3 -> 3x

=====================

Input: 4a

Output

1 -> 4a

2 -> 2y

3 -> 3x

4 -> Hello

What i want to do is:

Output

1 -> 4a

2 -> 1z

3 -> 2y

4 -> 3x

What should i do?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 1000

struct input{
  char input_name[SIZE];
};

int main(){    
  int i, startNum;
  struct input *str;
  char _startNum[SIZE];
  char _mode[SIZE];

  fputs("****Choose Menu****\n", stderr);    
  fputs("\n**Initialize items**\nNumber of products: ", stderr);
  fgets(_startNum, SIZE, stdin);
  startNum = atoi(_startNum);

  str = (struct input*)malloc(startNum * sizeof(struct input));
  if (str == NULL){
    printf("Memory allocation error\n");
    exit(EXIT_FAILURE);
  }

  for(i = 0; i < startNum; i++){
    printf("Enter name: ");
    fgets((str+i)->input_name, sizeof(struct input), stdin);
  }
  printf("\n");


  fputs("\n**Output**\n", stderr);  
  for(i = 0; i < startNum; i++){
    printf("%d -> %s", i+1, (str+i)->input_name);
  }
  printf("\n");

  startNum++;

  strcpy((str+startNum-1)->input_name, "Hello");
  for(i = startNum - 1; i = 0; i--){
    strcpy((str+i)->input_name,(str+i-1)->input_name);
  }

  fputs("Input: ", stderr); 
  fgets((str+0)->input_name, SIZE, stdin);

  fputs("\n**Output**\n", stderr);  
  for(i = 0; i < startNum; i++){
    printf("%d -> %s", i+1, (str+i)->input_name);
  }
  fputs("\n", stderr);

  return EXIT_SUCCESS;
}

Solution

  • If I have understood correctly then you need the following

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define SIZE 1000
    
    struct input{
      char input_name[SIZE];
    };
    
    int main( void )
    {    
      int i, startNum;
      struct input *str;
      char _startNum[SIZE];
      char _mode[SIZE];
    
      fputs("****Choose Menu****\n", stderr);    
      fputs("\n**Initialize items**\nNumber of products: ", stderr);
      fgets(_startNum, SIZE, stdin);
      startNum = atoi(_startNum);
    
      str = (struct input*)malloc(startNum * sizeof(struct input));
      if (str == NULL){
        printf("Memory allocation error\n");
        exit(EXIT_FAILURE);
      }
    
      for(i = 0; i < startNum; i++){
        printf("Enter name: ");
        fgets((str+i)->input_name, SIZE, stdin);
      }
      printf("\n");
    
    
      fputs("\n**Output**\n", stderr);  
      for(i = 0; i < startNum; i++){
        printf("%d -> %s", i+1, (str+i)->input_name);
      }
      printf("\n");
    
      startNum++;
    
    
      struct input tmp =  realloc(str, startNum * sizeof(struct input));
      if (tmp == NULL){
        printf("Memory reallocation error\n");
        exit(EXIT_FAILURE);
      }
    
      str = tmp;
    
      strcpy((str+startNum-1)->input_name, "Hello");
      for(i = startNum - 1; i != 0; i--){
        strcpy((str+i)->input_name,(str+i-1)->input_name);
      }
    
      fputs("Input: ", stderr); 
      fgets((str+0)->input_name, SIZE, stdin);
    
      fputs("\n**Output**\n", stderr);  
      for(i = 0; i < startNum; i++){
        printf("%d -> %s", i+1, (str+i)->input_name);
      }
      fputs("\n", stderr);
    
      free( str );
    
      return EXIT_SUCCESS;
    }
    

    As for your code then it has undefined behavior because there was not allocated memory for the appended element.

    And there is a typo in this loop

    for(i = startNum - 1; i = 0; i--){
                          ^^^^^
    

    where instead of comparison there is used assignment.

    Also instead of this call

    fgets((str+i)->input_name, sizeof(struct input), stdin);
    

    in general you have to use

    fgets((str+i)->input_name, sizeof((str+i)->input_name), stdin);
    

    or

    fgets((str+i)->input_name, SIZE, stdin);