Thread: How to add dynamic memory allocation

  1. #1
    Registered User
    Join Date
    Apr 2019
    Posts
    2

    How to add dynamic memory allocation

    Hi everyone, i'm currently learning how to use C coding and been told to use the following: A menu, Structures, File handling and Dynamic memory allocation to collect data off x amount of people and i don't have a clue where to start to add dynamic memory allocation to the code. this is what i have so far.


    Code:
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    #include<string.h>
    
    struct database 
    {
       char  fname[20],lname[20],email[35];
       float tel_number;
    };
    
    struct database input;
    char  others='y';
    
    void add()
    {
    FILE *datafile;
       struct database input;
     
    datafile = fopen ("data.dat","w");
       if (datafile == NULL)
       
         {
          fprintf(stderr, "\nError opening data.dat\n\n");
          exit (1);
         }
     
       printf("\n\nEnter \"quit\" as the first name to terminate program when all data added, then restart and choose option 2 to view stored records.\n");
       while (1)
     {
          printf("\nFirst Name: ");
          scanf ("%s", input.fname);
          if (strcmp(input.fname, "quit") == 0)
         exit(1);
          printf("Last Name: ");
          scanf ("%s", input.lname);
          printf("Telephone Number: +44");
          scanf ("%f", &input.tel_number);
          printf("Email Address: ");
          scanf ("%s", input.email);
          
                fwrite (&input, sizeof(struct database), 1, datafile);
      }
     
     printf("Do you want to exit? y/n");
     others=getche();
    
    }
    void read()
    {
       FILE *infile;
       infile = fopen ("data.dat","r");
       if (infile == NULL)
         {
          fprintf(stderr, "\nError opening data\n\n");
          exit (1);
         }
    
        while (fread (&input, sizeof(struct database), 1, infile))
          printf ("\nName = %s %s Telephone = +44%.0f Email Address = %s,",input.fname, input.lname,  input.tel_number, input.email);
    getch();
    }
     
    int main()
    {
    char choice;
    while(others=='y')
    {
         printf("Choose an option\n\n");
         printf("1.Add Records \n");
         printf("2.Show Records \n");
         printf("Your Choice: ");
         choice=getche();
         switch(choice)
    {
    case '1':
       add();
       break;
    case '2':
       read();
       break;
    case '3':
         exit(0);
    }
    printf("\nDo you want to continue? y/n");
    others=getche();
    }
    getch();
    return 0;
    }
    Last edited by JJ57663; 04-26-2019 at 02:04 PM.

  2. #2
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    I see that you haven't gone through all of what laserlight suggested
    Quite a few things to change:


    • Move the struct database declaration to before the main function definition.
    • I would rename struct database to struct person as it is more a record of a person than a database in itself.
    • Indent your code properly, i.e., pick a fixed number of spaces (typically 2, 4, or 8; I suggest 4) or a tab as a level of indentation, and consistently apply it.
    • Use descriptive variable names, e.g., s is a poor name for "how many people". Better examples include people_num or people_count.
    • You have a comment that says "pointer declared", but you didn't actually declare a pointer.
    • Check the return value of scanf.
    • Be aware that your use of scanf leaves the newline from entering the input in the input buffer where it might be read by a subsequent call to fgets. One way to avoid this is to use fgets with sscanf instead of scanf.
    • You need to assign the return value of malloc to a pointer. Also, there's no need to cast the return value of malloc.
    • You shouldn't be calling fopen in a loop. You should call it before the loop.
    • Since you're using fwrite, open the file with "wb" as the mode instead of "w".
    • If fopen was successful, remember to call fclose at some point.
    • Never use the gets function. The fgets function is an alternative, but be aware that if there's space to store the newline character from entering the input, it will store that newline character. Remember to check the return value of fgets.
    • Your attempt to print the records seems to be printing the same record (i.e, the last one) over and over again. Perhaps you want to read from the file that was recently written to (after closing it) in order to check that it was written correctly? If not, you apparently will have a dynamic array, so you perhaps you could print its content.
    • Remember to free what you malloc.
    • You don't actually need to #include <conio.h> and call getch. They are non-standard. Just run your program from a command prompt window, or from an IDE that will pause the program for you when it ends.
    • Consider breaking up your main function into smaller functions that each does one thing and does it well.
    laserlight is one one the best C programmers that you are going to encounter on the internet - I can't advise you to follow that advice more...


    "conio.h" is a powerful header if you are making a programme for a Microsoft console window, or MS-DOS - It has a good interface for changing colours and doing things like printing text anywhere on the screen. However, this is not how programmes are made anymore, and will probably lose you points on your assignment because you are destroying portability.

    The only reason that you need it in your programme is for getch and getche - If you swap them with getchar() from stdio, you will be better off. Only using conio for getch() does not justify its inclusion.


    To start with dynamic memory allocation...

    Do you have any lecture/tutorial notes? Do you have a course textbook?

    Dynamically allocated memory is memory requested at runtime - You are also required to free it at runtime. If you don't, your programme has something called a memory leak.

    You then access the memory that you requested through a pointer.

    Tips - Always check to see if the result isn't NULL before using it; always make sure that the memory is freed using "free(..)" even if something fails; don't accidently lose the address of that memory.

    I happen to have some code with an example from something I did the other day...
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    
    int main(void)
    {
        char *apple = NULL;
        int appleArraySize = 5;
        
        int *banana = NULL;
    
        long int *grape = NULL;
    
    
        int result = EXIT_SUCCESS;
    
    
        if (NULL == (apple = malloc(appleArraySize * sizeof(*apple))))
        {
            result =  EXIT_FAILURE;
        }
    
        free(apple);
    
    
        if (NULL == (banana = malloc(sizeof(*banana))))
        {
            result =  EXIT_FAILURE;
        }
    
        free(banana);
    
    
        if (NULL == (grape = malloc(sizeof(*grape))))
        {
            result =  EXIT_FAILURE;
        }
    
        free(grape);
    
    
        return result;
    }
    C dynamic memory allocation - Wikipedia
    Fact - Beethoven wrote his first symphony in C

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dynamic memory Allocation
    By exclusive in forum C Programming
    Replies: 4
    Last Post: 11-10-2011, 07:16 AM
  2. Memory dynamic allocation
    By elvio.vicosa in forum C Programming
    Replies: 8
    Last Post: 10-16-2007, 03:30 AM
  3. Help with dynamic memory allocation
    By malooch in forum C Programming
    Replies: 2
    Last Post: 12-13-2006, 01:26 PM
  4. Dynamic memory allocation...
    By dicorr in forum C Programming
    Replies: 1
    Last Post: 06-24-2006, 03:59 AM
  5. dynamic memory allocation
    By mag_chan in forum C Programming
    Replies: 13
    Last Post: 10-21-2005, 07:54 AM

Tags for this Thread