Thread: loading files, and memory allocation

  1. #1
    Registered User
    Join Date
    Apr 2006
    Posts
    6

    loading files, and memory allocation

    i have written a database program for a course i am doing and there is one major bug.
    when loading a saved file. and then displaying that data characters are added to the data. if i then load the file again, most of the characters disapear, however not all of them.

    unfortunatly im not sure where the problem lyes so i feel i should post the entire code and header file.

    Code:
    #include <stdio.h>      /*included library files*/
    #include <conio.h>
    #include <alloc.h>
    #include <stdlib.h>
    #include <C:\my documents\database.h>
    
    void main(void)    /*main program*/
    {
    unsigned menu,i,entry=0,del,edit; /*declare variables*/
    struct details *p;
    char ans;
    char file_name [file_name_length];
    
    clrscr();
    flushall();/*clears stdin(and all streams)*/
    /*allocates memory for database, and returns error if not available*/
    if((p = (struct details *)calloc(1, (sizeof(struct details))))==NULL)
         {
         printf("Cannot allocate memory");
         getch();
         }
    
    do
    {
    
    printf("\n1. Enter data\n2. Edit data\n3. Delete data\n4. Display data\n5. Save data\n6. Load data\n7. Quit");
    printf("\nSelect an option (1-7): ");/*request input*/
    scanf("%u",&menu);
    realloc(p,entry);
    
    switch(menu)   /*set menu as a switch function*/
    	{
    	case 1:  /*if menu=1 this code will be executed*/
    
              printf("\nEnter Details:");
                do
    	         {
                p[entry]= enter_details(entry);
                printf("Enter more detials? y/n: ");
                ans=getchar();
                entry++;
                }
                while (ans!='n');
    
                break;
    	case 2:  flushall();/*if menu=2 this code will be executed*/
                clrscr();
                printf("\nEdit Data:\nEnter number of record to edit: ");
                scanf("%u",&edit);
                printf("\nRecord Number:%u",edit);
                print_details(p[(edit-1)]);
                printf("\nPress a key to edit this record");
                getch();
                p[(edit-1)]=enter_details((edit-1));
    
    		      break;
       case 3:  flushall();/*if menu=3 this code will be executed*/
                printf("\nDelete Data:\nEnter number of the record you wish to delete: ");
                scanf("%u",&del);
                break;
    	case 4:  flushall();/*if menu=4 this code will be executed*/
                clrscr();
                printf("\nDisplay Data:\n");
                i=0;
                do
                {
                printf("\nRecord Number:%u",(i+1));
                print_details(p[i]);
                i++; }
                while (i<entry);
    
    		      break;
    	case 5:  flushall();/*if menu=5 this code will be executed*/
                printf("\nSave Data:\nEnter full Filename: ");
                gets(file_name);
                if ((save_data(entry,file_name,p))==1)
                printf("\nFile saved successfully\n");
                else printf("\nError: File not saved\b");
    		      break;
    	case 6:  flushall();/*if menu=6 this code will be executed*/
                printf("\nLoad Data:\nWARNING:All unsaved data will be lost\nEnter full Filename: ");
                gets(file_name);
                entry=(load_data(file_name,(p)));
                printf("%u records loaded",entry);
                break;
    	}
    
    }
    while (menu!=7);
      clrscr();
      printf("Press any key to exit");
      getch();
      free(p);
    
    }
    and the header file
    Code:
    #define name_length 15     /*defined data lengths*/
    #define address_length 30
    #define email_length 25
    #define telephone_length 20
    #define file_name_length 20
    
    struct details enter_details(int);   /*function prototypes*/
    void print_details(struct details);
    int save_data(int, char [], struct details *);
    int load_data(char [], struct details *);
    
    struct details   /*Structure format*/
     {
       char surname[name_length];
       char forename[name_length];
       char address[address_length];
       char telephone[telephone_length];
       char email[email_length];
      };
    
    struct details enter_details(int i)
    {
    struct details get_member;
    flushall();
       printf("\nEnter Surname %d : ",(i+1));
       gets(get_member.surname);
       printf("\nEnter Forename %d : ",(i+1));
       gets(get_member.forename);
       printf("\nEnter Address %d : ",(i+1));
       gets(get_member.address);
       printf("\nEnter Telephone Number %d : ",(i+1));
       gets(get_member.telephone);
       printf("\nEnter Email Address %d : ",(i+1));
       gets(get_member.email);
    
       return get_member;
    }
    
    void print_details(struct details print_details)
    {
       printf("\nName: %s, %s ",print_details.surname,print_details.forename);
       printf("\nAddress: %s",print_details.address);
       printf("\nTelephone: %s",print_details.telephone);
       printf("\nEmail: %s\n",print_details.email);
    
    }
    
    int save_data(int entrys, char filename[], struct details *fileptr)
    {
    FILE *fptr;
    if((fptr = fopen(filename,"wb"))==NULL)
    	{
       printf("File cannot be opened\n");
       exit(1);
       return 0;
       }
    
    fwrite(fileptr,sizeof(struct details),entrys,fptr);
    fclose(fptr);
    return 1;
    }
    
    int load_data(char filename[],struct details *fileptr)
    {
    int i=0;
    FILE *fptr;
    
    clrscr();
    if((fptr = fopen(filename,"rb"))==NULL)/*open file*/
    	{
       printf("File cannot be opened\a");
       getch();
       exit(1);
       return NULL;
       }
    while(!feof(fptr))        /*while not at the end of the file*/
    	{
       getc(fptr);            /*load bit of file*/
       i++;                   /*incrememnt size of file*/
    	}
    i=(i/(sizeof(struct details)));
    fclose(fptr);
    
    realloc(fileptr,i);
    if((fptr = fopen(filename,"rb"))==NULL)
         {
          printf("File cannot be opened\a");
          getch();
          exit(1);
          return 0;
         }
    fread(fileptr,sizeof(struct details),i,fptr);
    fclose(fptr);
    return i;
    }
    i hope someone has the time to look throuh it for me

  2. #2
    Sys.os_type="Unix";;
    Join Date
    Aug 2005
    Posts
    52
    What do you think realloc returns?

  3. #3
    Registered User
    Join Date
    Apr 2006
    Posts
    6
    as far as i know realloc doesnt return anything. it just changes the size of the memory allocated at pointer p.

  4. #4
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Quote Originally Posted by Rard
    as far as i know realloc doesnt return anything. it just changes the size of the memory allocated at pointer p.
    Nope. Realloc returns a pointer to the reallocated memmory just like malloc. And just like malloc, you need to use this pointer, becouse it might point to a different location than pointer you pass to it.

  5. #5
    Registered User
    Join Date
    Apr 2006
    Posts
    6
    ahh, right so if after realloc the pointer is different my program could be looking at small bits of data just before where its supposed to be and displaying that. i noticed another problem with that line. where i had entry it should have entry*sizeof(struct details)

    thanks for the help!

  6. #6
    Registered User
    Join Date
    Apr 2006
    Posts
    6
    ok i changed that line to this
    Code:
    p = (struct details *)realloc(p,(entry*(sizeof(struct details))));
    but now when i try to load a file or add data it exits the program. i cant understand why it would do that

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > void main(void)
    See the FAQ

    > gets(get_member.surname);
    See the FAQ

    > flushall();/*clears stdin(and all streams)*/
    Seems like fflush(stdin) to me - guess what, that's in the FAQ too

    > p = (struct details *)calloc(1, (sizeof(struct details)))
    Mmm, casting malloc - you guessed it, that's in the FAQ

    > #include <alloc.h>
    Which stone-age compiler are you using?
    No wait, don't tell me - it's TurboC and your machine is running XP
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User wintellect's Avatar
    Join Date
    Mar 2006
    Posts
    24
    Quote Originally Posted by Rard
    ok i changed that line to this
    Code:
    p = (struct details *)realloc(p,(entry*(sizeof(struct details))));
    And straight from the man page malloc(3):

    When using realloc() one must be careful to avoid the following idiom:
    Code:
               nsize += 50
               if ((p = realloc(p, nsize)) == NULL)
                       return (NULL);
    Do not adjust the variable describing how much memory has been allocated until one knows the allocation has been successful. This can cause aberrant program behavior if the incorrect size value is used. In most cases, the above sample will also result in a leak of memory. A return value of NULL indicates that the old object still remains allocated. Better code looks like this:
    Code:
               newsize = size + 50;
               if ((p2 = realloc(p, newsize)) == NULL) {
                       if (p)
                               free(p);
                       p = NULL;
                       return (NULL);
               }
               p = p2;
               nsize = newsize;
    I love UNIX for the online documentation

  9. #9
    Registered User
    Join Date
    Apr 2006
    Posts
    6
    ok i admit it, i didnt read the faq, i didnt actualy see a link. but i know from forums i have been involved in its annoying when people ask stupid things. so i appreciate the help.
    also 'Salem' im using borland C++ not out of choice but because i'm told to. I do electronic engineering and borland can complile for really old proccessors, so we are told to get used to it.
    Telect, i was actualy going to try that but the help pages in borland showed an example exactly how i used it.
    Last edited by Rard; 04-20-2006 at 05:27 AM.

  10. #10
    Registered User
    Join Date
    Apr 2006
    Posts
    6
    i have tried various ways of using realloc in this code. but it seems like everytime it comes back to this part of the code it just exits the program without warning. could someone please give me as specific example of how you would use realoc in my code.

  11. #11
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    p = (struct details *)realloc(p,(entry*(sizeof(struct details))));
    The only place in your code that I found where you call realloc() you call it with a value of 0 for entry.
    If you do that with VC6 realloc returns NULL.
    If you then dereference p -> booooom.
    Kurt

  12. #12
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    If you are using a single source file for the program your overall setup is fine. If you switch to a multifile project however and need to include that header you're going to run into problems (linker errors). You should avoid putting code in headers if at all possible.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  13. #13
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    The only place in your code that I found where you call realloc() you call it with a value of 0 for entry.
    If you do that with VC6 realloc returns NULL.
    If you then dereference p -> booooom.
    Calling realloc() with 0 as its second parameter is exactly the same as calling free().
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  14. #14
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by dwks
    Calling realloc() with 0 as its second parameter is exactly the same as calling free().
    gcc 3.3 returns the 1st parameter in that case.
    Kurt

  15. #15
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    From http://www.opengroup.org/onlinepubs/.../realloc.html:
    If size is 0, either a null pointer or a unique pointer that can be successfully passed to free() shall be returned.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Loading files into memory
    By アストラル in forum C++ Programming
    Replies: 22
    Last Post: 09-20-2008, 04:49 PM
  2. To find the memory leaks without using any tools
    By asadullah in forum C Programming
    Replies: 2
    Last Post: 05-12-2008, 07:54 AM
  3. reading files into memory
    By bobthebullet990 in forum C Programming
    Replies: 3
    Last Post: 11-30-2005, 03:39 PM
  4. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  5. Manipulating the Windows Clipboard
    By Johno in forum Windows Programming
    Replies: 2
    Last Post: 10-01-2002, 09:37 AM