Thread: dynamically allocating memory

  1. #1
    Registered User
    Join Date
    Sep 2013
    Posts
    82

    dynamically allocating memory

    hello, I have created a database for music cds:
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #define array
    typedef struct cd_database
    {
         char   artist[200];
         char   title[200];
         int    tracks;
         int    album;
         float  price;
    }cd_t;
    #ifndef array
    cd_t   *cds;
    #else
    cd_t   cds[100];
    #endif
    char   fname[100];
    int    changes = 0;
    int    count = 0;
    
    #define FLUSH   while((ch = getchar()) != '\n' && ch != EOF)
    
    
    void quit_program()
    {
        puts("Thanks for using the database. Have a nice day...");
        system("pause");
    }
    
    int yesno(char prompt[])
    {
        char  answer;
        
        for(;;)
        {
           printf("%s (Y/N)? ",prompt);
           fflush(stdin);
           scanf (" %c",&answer);
        
           answer = toupper(answer);
           if(answer == 'Y')
              return 1;
           if(answer == 'N')
              return 0;
        }
    }
    
    are_you_sure()
    {
        if(!changes)
            return 1;
            
        return yesno("Are you sure you want to discard all records?");
    }
    
    reset_all()
    {
        changes = 0;
        fname[0] = '\0';
    }
    
    input()
    {
           printf("Title: ");
           fflush(stdin);
           scanf ("%[^\n]",cds[count].title);
           
           printf("Artist: ");
           fflush(stdin);
           scanf ("%[^\n]",cds[count].artist);
           
           printf("Tracks: ");
           fflush(stdin);
           scanf ("%d",&cds[count].tracks);
           
           cds[count].album = yesno("Album? ");
           
           printf("Price: ");
           fflush(stdin);
           scanf ("%f",&cds[count].price);
    }
    
    output(int i, FILE *fptr)
    {
            printf("Title: %s\n",cds[i].title);
            printf("Artist: %s\n",cds[i].artist);
            printf("Tracks: %d\n",cds[i].tracks);
            
            if(cds[i].album == 1)
                printf("Album\n");
            else
                printf("Single\n");
            
            printf("Price: %.2f\n\n",cds[i].price);
    }
    int main(void)  
    {
        atexit(quit_program);
        
        for(;;)
           menu();
           
        return 0;
    }
    
    menu()
    {
        int choice;
        int ch;
        
        /*forever loop until user enters a valid choice*/
        for(;;)
        {  
           printf("Current file open: %s\n\n",fname);
           printf("Welcome to CD database...\n\n");
           printf("Enter your choice:\n"
                  "    1. File: Create a new list\n"
                  "    2.       Open an existing list\n"
                  "    3.       Save list\n"
                  "    4.       Save the list with a new name\n"
                  "    5.       Append list to another file\n"
                  "    6. Edit: Create a new record\n"
                  "    7. View: Display a specific record\n"
                  "    8.       Display all records\n"
                  "    9. Exit\n");
           
           scanf("%d",&choice);
           FLUSH;
           
              if(choice == 1)
              {
                     file_new();
                     break;
              }
              else if(choice == 2)
              {
                     file_open();
                     break;
              }
              else if(choice == 3)
              {
                     file_save();
                     break;
              }
             /* else if(choice == 4)
              {
                     file_saveas();
                     break;
              }
              else if(choice == 5)
              {
                     file_append();
                     break;
              }*/
              else if(choice == 6)
              {
                     new_record();
                     break;
              }
              /*else if(choice == 7)
              {
                     specific_record();
                     break;
              }*/
              else if(choice == 8)
              {
                     all_records();
                     break;
              }
              else if(choice == 9)
              {
                     exit(0);
                     break;
              } 
        }
    }
    
    //option 1:
    file_new()
    {
        if(are_you_sure())
            reset_all();
        system("cls");
        
        return;
    }
    
    //option 2:
    file_open()
    {
        printf("Enter the name of the file you would like to open: ");
        fflush(stdin);
        fgets (fname,sizeof(fname),stdin);
        fname[strlen(fname)-1] = '\0';
       // strcat(fname,".txt");
        
        return;
    }
    
    //option 3:
    file_save()
    {
        FILE   *fptr;
        int    i;
        
        fptr = fopen(fname,"wb");
        if (fptr == NULL)
        {
                 perror("Could not write to file");
                 return;
        }
        for(i = 0; i < count; i++)
        fwrite(&cds,sizeof(cd_t),1,fptr);
        
        fclose(fptr);
        return;
    }
    
    //option 6:
    new_record()
    {
        int i = count;        
        
        printf("Enter your record\n");
    #ifndef array
        if((cds = realloc(cds, sizeof(cd_t) * (i+1))) == NULL)
        {
                perror("Could not locate enough memory");
                return;
        }
    #endif
        
        input();
        count++;
        
        return;
    }
    
    //option 8:
    all_records()
    {
        FILE  *fptr;
        int   i=0;
        
        fptr = fopen(fname,"rb");
        if(fptr == NULL)
        {
         perror("Could not open");
         return;
        }
        
        printf("Records\n");
        
        while(fread(&cds,sizeof(cd_t),1,fptr) == 1)
        {
             output(i,fptr);
             i++;
        }
        
        fclose(fptr);
        return;
    }
    When I am using malloc instead of arrays the code is not working properly after exit. I have tried alot but can't came up with a way, can someone please help me out. Thanks in advance

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    You actually haven't shown the code using malloc(). You haven't described the symptoms that lead you to conclude the program using malloc() is malfunctioning. How do you expect people to guess what you've done wrong? Few forum members are telepathic.

    Try creating a SMALL but complete sample of code which actually illustrates your problem.

    On a quick look, your calls to fwrite() and fread() will probably break if you supply a malloc'ed pointer rather than an array.

    Also fflush(stdin) has undefined behaviour. It is not guaranteed to discard pending input. Undefined behaviour tends to make programs unpredictable.

    And don't rely on the compiler inferring return types of functions. That has been considered bad technique for about 20 years now. You might as well use techniques that are considered appropriate in this century.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    Registered User
    Join Date
    Sep 2013
    Posts
    82
    Quote Originally Posted by grumpy View Post
    You actually haven't shown the code using malloc(). You haven't described the symptoms that lead you to conclude the program using malloc() is malfunctioning. How do you expect people to guess what you've done wrong? Few forum members are telepathic.

    Try creating a SMALL but complete sample of code which actually illustrates your problem.

    On a quick look, your calls to fwrite() and fread() will probably break if you supply a malloc'ed pointer rather than an array.

    Also fflush(stdin) has undefined behaviour. It is not guaranteed to discard pending input. Undefined behaviour tends to make programs unpredictable.

    And don't rely on the compiler inferring return types of functions. That has been considered bad technique for about 20 years now. You might as well use techniques that are considered appropriate in this century.
    Am sorry man, was in a hurry so just posted the code. I know fflush(stdin) is wrong, and I haven't declared function types. I just want to make the code work for now, it's an exercise and I have been dealing with it for two weeks, let me just edit the code, and thanks for making me aware.

  4. #4
    11DE784A SirPrattlepod's Avatar
    Join Date
    Aug 2013
    Posts
    485
    Quote Originally Posted by grumpy View Post
    Few forum members are telepathic.
    I am. Pick a card, any card, think about it carefully and I'll know what card you picked.

  5. #5
    Registered User
    Join Date
    Sep 2013
    Posts
    82
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #define array
    typedef struct cd_database
    {
         char   artist[200];
         char   title[200];
         int    tracks;
         int    album;
         float  price;
    }cd_t;
    #ifndef array
    cd_t   *cds;
    #else
    cd_t   cds[100];
    #endif
    char   fname[100];
    int    changes = 0;
    int    count = 0;
     
    #define FLUSH   while((ch = getchar()) != '\n' && ch != EOF)
     
     
    void quit_program()
    {
        puts("Thanks for using the database. Have a nice day...");
        system("pause");
    }
     
    int yesno(char prompt[])
    {
        char  answer;
         
        for(;;)
        {
           printf("%s (Y/N)? ",prompt);
           fflush(stdin);
           scanf (" %c",&answer);
         
           answer = toupper(answer);
           if(answer == 'Y')
              return 1;
           if(answer == 'N')
              return 0;
        }
    }
     
    int are_you_sure()
    
    {
        if(!changes)
            return 1;
             
        return yesno("Are you sure you want to discard all records?");
    }
     
    void reset_all()
    
    {
        changes = 0;
        fname[0] = '\0';
    }
     
    void input()
    
    {
           printf("Title: ");
           fflush(stdin);
           scanf ("%[^\n]",cds[count].title);
            
           printf("Artist: ");
           fflush(stdin);
           scanf ("%[^\n]",cds[count].artist);
            
           printf("Tracks: ");
           fflush(stdin);
           scanf ("%d",&cds[count].tracks);
            
           cds[count].album = yesno("Album? ");
            
           printf("Price: ");
           fflush(stdin);
           scanf ("%f",&cds[count].price);
    }
     
    void output(int i, FILE *fptr)
    
    {
            printf("Title: %s\n",cds[i].title);
            printf("Artist: %s\n",cds[i].artist);
            printf("Tracks: %d\n",cds[i].tracks);
             
            if(cds[i].album == 1)
                printf("Album\n");
            else
                printf("Single\n");
             
            printf("Price: %.2f\n\n",cds[i].price);
    }
    int main(void)  
    {
        atexit(quit_program);
         
        for(;;)
           menu();
            
        return 0;
    }
     
    void menu()
    
    {
        int choice;
        int ch;
         
        /*forever loop until user enters a valid choice*/
        /*I have removed choice 4,5 and 7 cause I don't want them for now*/
    
    
        for(;;)
        {  
           printf("Current file open: %s\n\n",fname);
           printf("Welcome to CD database...\n\n");
           printf("Enter your choice:\n"
                  "    1. File: Create a new list\n"
                  "    2.       Open an existing list\n"
                  "    3.       Save list\n"
                  "    4.       Save the list with a new name\n"
                  "    5.       Append list to another file\n"
                  "    6. Edit: Create a new record\n"
                  "    7. View: Display a specific record\n"
                  "    8.       Display all records\n"
                  "    9. Exit\n");
            
           scanf("%d",&choice);
           FLUSH;
            
              if(choice == 1)
              {
                     file_new();
                     break;
              }
              else if(choice == 2)
              {
                     file_open();
                     break;
              }
              else if(choice == 3)
              {
                     file_save();
                     break;
              }
             /* else if(choice == 4)
              {
                     file_saveas();
                     break;
              }
              else if(choice == 5)
              {
                     file_append();
                     break;
              }*/
              else if(choice == 6)
              {
                     new_record();
                     break;
              }
              /*else if(choice == 7)
              {
                     specific_record();
                     break;
              }*/
              else if(choice == 8)
              {
                     all_records();
                     break;
              }
              else if(choice == 9)
              {
                     exit(0);
                     break;
              } 
        }
    }
     
    //option 1:
    file_new()
    {
        if(are_you_sure())
            reset_all();
        system("cls");
         
        return;
    }
     
    //option 2:
    file_open()
    {
        printf("Enter the name of the file you would like to open: ");
        fflush(stdin);
        fgets (fname,sizeof(fname),stdin);
        fname[strlen(fname)-1] = '\0';
       // strcat(fname,".txt");
         
        return;
    }
     
    //option 3:
    file_save()
    {
        FILE   *fptr;
        int    i;
         
        fptr = fopen(fname,"wb");
        if (fptr == NULL)
        {
                 perror("Could not write to file");
                 return;
        }
        /*fwrite works perfectly, 90% sure, cause before I fwrite I am changing cd structure to arrays by use of malloc*/
    
    
        for(i = 0; i < count; i++)
    
        fwrite(&cds,sizeof(cd_t),1,fptr);
         
        fclose(fptr);
        return;
    }
     
    //option 6:
    new_record()
    {
        int i = count;        
         
        printf("Enter your record\n");
    #ifndef array
        if((cds = realloc(cds, sizeof(cd_t) * (i+1))) == NULL)
        {
                perror("Could not locate enough memory");
                return;
        }
    #endif
         
        input();
        count++;
         
        return;
    }
     
    //option 8:
    all_records()
    {
        FILE  *fptr;
        int   i=0;
         
        fptr = fopen(fname,"rb");
        if(fptr == NULL)
        {
         perror("Could not open");
         return;
        }
         
        printf("Records\n");
         /*here is the problem. It works fine before exit but after exit it doesn't. I think I need a way of changing the structure to array by malloc somehow before fread'ing*/
    
        while(fread(&cds,sizeof(cd_t),1,fptr) == 1)
        {
             output(i,fptr);
             i++;
        }
         
        fclose(fptr);
        return;
    }
    I again apologise for previous code, and I know fflush(stdin) is wrong, but for now i just need the code to work. Sorry and thanks.

  6. #6
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    You should use a switch and a case for your if-statement block.

    Instead of
    Code:
    if (x == 1) {
    
    } else if (x == 2) {
    
    } else if (x == 3) ...
    it might be cleaner and help you visualize the code better if you write,
    Code:
    switch (x) {
    
       case 1 :
    /* Code goes here */
          break;
    
        case 2 :
           break;
    
        case 3 :
           break;
    
    ....
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. dynamically allocating memory
    By rs07 in forum C Programming
    Replies: 6
    Last Post: 09-14-2008, 03:26 AM
  2. Dynamically allocating memory
    By abh!shek in forum C++ Programming
    Replies: 8
    Last Post: 02-21-2008, 09:59 AM
  3. Dynamically allocating memory...
    By Junior89 in forum C++ Programming
    Replies: 28
    Last Post: 05-08-2007, 10:17 PM
  4. Dynamically allocating memory for strings in a function
    By sunilkjin in forum C Programming
    Replies: 6
    Last Post: 11-22-2006, 04:43 PM
  5. Help me with dynamically allocating!
    By Trauts in forum C++ Programming
    Replies: 6
    Last Post: 02-27-2003, 06:05 PM

Tags for this Thread