Thread: question about malloc() and free()

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    2

    question about malloc() and free()

    hi all,

    I was reading through an old C tutorial and I tried this program on my pc:
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    main( )
    { struct animal 
      { char name[25];
        char breed[25];
        int age;
      } *pet1, *pet2;
      
      pet2 = malloc(sizeof(struct animal));
      strcpy(pet2->name,"Krystal");
      strcpy(pet2->breed,"German Shepard");
      pet2->age = 4;
      
         /*   now print out the data described above */
    
      printf("%s is a %s, and is %d years old.\n",pet2->name,pet2->breed, pet2->age); 
      pet1 = pet2;    /* pet1 now points to the same structure that pet3 points to                        */
      free(pet2);     /* this frees up one structure                */
    
     printf("%s is a %s, and is %d years old.\n",pet1->name,pet1->breed, pet1->age);
    }
    why is this program's output:

    Krystal is a German Shepard, and is 4 years old.
    is a German Shepard, and is 4 years old.

    instead of what I supposed it should be?:

    Krystal is a German Shepard, and is 4 years old.
    is a German Shepard, and is years old.

    why does the 4 remain after free() ?

    thanks a lot

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Code:
    main( )
    { struct animal 
      { char name[25];
        char breed[25];
        int age;
      } *pet1, *pet2;
    First, main returns int: http://cpwiki.sourceforge.net/Implicit_main
    Secondly, please avoid putting code on the opening {. It hurts readability, just as placing the } on anything but a new line.
    And as for your question, it's undefined behavior. It's freed, alright, so whether or not that data is left is up to the OS. What YOU need to know is that you told the OS you no longer need it, so don't use it.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    The program assigns pet1 to pet2. Now you can free pet2, but that doesn't zero out the struct's memory values. It just marks that struc's memory as "available" for the heap.
    Last edited by Adak; 01-24-2009 at 09:30 AM.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    why does the 4 remain after free() ?
    Because pet1 was not freed, and so now points to where pet2 did. Since pet1 was not allocated anything and pet2 was freed, this memory can be overwritten, but has not been because nothing else has happened. For example, with my compiler if I add the following:
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    main( )
    { struct animal 
      { char name[25];
        char breed[25];
        int age;
      } *pet1, *pet2, *pet3;
    char *this;
      
      pet2 = malloc(sizeof(struct animal));
      strcpy(pet2->name,"Krystal");
      strcpy(pet2->breed,"German Shepard");
      pet2->age = 4;
      
         /*   now print out the data described above */
    
      printf("%s is a %s, and is %d years old.\n",pet2->name,pet2->breed, pet2->age); 
      pet1 = pet2;    /* pet1 now points to the same structure that pet3 points to                        */
      free(pet2);     /* this frees up one structure                */
    
    pet3=malloc(sizeof(struct animal));
      strcpy(pet3->name,"Ecstacy");
      strcpy(pet3->breed,"Golden Lab");
     printf("%s is a %s, and is %d years old.\n",pet1->name,pet1->breed, pet1->age);
         printf("pet3 age=%d\n",pet3->age)
    }
    The output is:
    Krystal is a German Shepard, and is 4 years old.
    Ecstacy is a Golden Lab, and is 4 years old.
    pet3 age=4

    pet1 (mysteriously and apparently) now points to pet3, and pet3 apparently has inherited pet2's age! This is beacause pet3 is stored in the same physical location as pet2 was -- the memory was freed for other use, not erased -- and pet1 still points to this location.

    However, there is no guarantee the compiler (linker?) will actually do that, so it's not a technique to be used in programming.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The compiler does nothing. The operating system itself controls that aspect.
    Also remember that your code is undefined and is not and never guaranteed to "inherit" some memory previously used.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Elysia View Post
    The compiler does nothing. The operating system itself controls that aspect.
    points taken
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    2
    very clear now. thanks.

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    The compiler does nothing. The operating system itself controls that aspect.
    Also remember that your code is undefined and is not and never guaranteed to "inherit" some memory previously used.
    To be pedantic, malloc and free are C runtime library functions, not OS functions [although they will usually have to interact with the OS to get blocks of memory, but since it's quite time-consuming to call the OS to get more memory, the heap management functions in the C library will normally call the OS to get a fairly large block of memory (say 64KB or more), and then split that into smaller pieces as it sees fit].

    As to what happens when you free memory, it is indeed undefined, and "anything can happen". It gets even worse if you have multiple threads running in the system, because another thread may well allocate the memory that your thread is still using but has freed [or if you are writing drivers that free memory before the driver is finished with it, and another driver decides to allocate some memory - it can REALLY cause problems in this case. Imagine a file-system related driver allocating the same memory that I just freed for a write-buffer to a file, and my driver writing some data to the freed buffer - guess what: Your disk will need formatting pretty soon! (Don't ask how I know this )]

    Never EVER rely on the content or behaviour of pointers that have been freed - very bad.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Never EVER rely on the content or behaviour of pointers that have been freed - very bad.
    Just a few weeks ago I have fixed a bug like this
    Code:
    free(ptr);
    *ptr = 0;
    The bug was found due to crash that occured constanly on this line - but only on one computer during run of one specific scenario. Other computers and other scenarios were running other the place without a notice... I was lucky the crash occured in QA and not on the customer use
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. malloc calloc and free
    By -EquinoX- in forum C Programming
    Replies: 27
    Last Post: 03-26-2009, 10:59 AM
  2. Malloc - Free giving double free or corruption error
    By andrew.bolster in forum C Programming
    Replies: 2
    Last Post: 11-02-2007, 06:22 AM
  3. Replies: 12
    Last Post: 06-24-2005, 04:27 PM
  4. Ask about free funtion using with malloc
    By ooosawaddee3 in forum C++ Programming
    Replies: 1
    Last Post: 05-12-2002, 04:43 PM
  5. Malloc and Free.....
    By heljy in forum C Programming
    Replies: 5
    Last Post: 04-14-2002, 09:17 PM

Tags for this Thread