Thread: Environment variable corruption

  1. #1
    Registered User
    Join Date
    Jan 2004
    Posts
    22

    Environment variable corruption

    Hi, someone suggested I post this here. I'm writing a shell and my environment variables seem to get corrupted for strange reasons. Here is one example of code. The correlation seems to be with the free(path) line the and dirPtr = ... line. If I don't remove one or the other, the 2nd printing of NEWDIR is (null) or nonexistent since apparently NEWDIR dies. Any ideas?

    int main()
    {

    char *dirPtr;

    char *path;
    path = (char *)malloc(12);

    strcpy(path, "NEWDIR=/usr");

    putenv(path);

    free(path);

    std::cout << getenv("NEWDIR") << std::endl;
    dirPtr = (char *)malloc(5);
    std::cout << getenv("NEWDIR") << std::endl;

    free(dirPtr);
    return 0;

    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    DESCRIPTION
    The putenv() function adds or changes the value of environment vari‐
    ables. The argument string is of the form name=value. If name does
    not already exist in the environment, then string is added to the envi‐
    ronment. If name does exist, then the value of name in the environment
    is changed to value. The string pointed to by string becomes part of
    the environment, so altering the string changes the environment.
    Read the last sentence, then decide if freeing the memory is a good idea
    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.

  3. #3
    Registered User
    Join Date
    Jan 2004
    Posts
    22
    Interesting. I have read other places that a copy is made so it's ok. I'm only an average programmer. So, I always clean up any dynamically allocated memory I create. So, I guess this is ok not to clean up?

  4. #4
    Registered User
    Join Date
    Jan 2004
    Posts
    22
    Also, if I get rid of this line only:

    dirPtr = (char *)malloc(5);

    It seems to work out fine.

  5. #5
    .
    Join Date
    Nov 2003
    Posts
    307
    There are several malloc implementations - a malloc implementation also covers free() (or new and delete. Whichever applies.) malloc looks for the first memory chunk in the free list that is big enough to accomodate your request.
    Code:
    free(path);   <- this frees up a chunk at least 12 (+4) bytes long
    .............
    dirPtr=malloc(5); <- this needs only five (+4) bytes, so it re-uses the memory
    The +4 is there because malloc creates a memory descriptor that is two unsigned longs (each long is usually 4 bytes in 32 bit image files, check limits.h for your particular box - see LONG_MAX )

    The first long is the size, the second longword is the address that malloc returns. So, if you malloc(120), the algorithm looks for the first 124 byte-long free chunk.
    (This is how Doug Lea's malloc works, for example)

    It also explains your observation - malloc is re-using your memory. Which observation is a bad idea by the way. Don't free() the path variable.

    Period.

  6. #6
    Registered User
    Join Date
    Jan 2004
    Posts
    22
    Thanks for the replies. After testing, I see that not freeing the variable creates a memory leak. I call the test function in a loop and it eventually gives me a memory error, I suspect since I'm not freeing "path". Here is the test code:
    Code:
    void setpath()
    {
        char *path;
    
        path = (char *)malloc(13);
        if (path == 0)
    	printf("Memory allocation error.\n");
            
        strcpy(path, "NEWPATH=test");
    
        putenv(path);
    }
    Last edited by miclus; 10-01-2004 at 12:39 AM.

  7. #7
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Why are you bothering with malloc() ?

    >putenv("NEWPATH=test");
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  8. #8
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    free the previous path before setting the new one then.
    Code:
    void setpath()
    {
        static char *path = NULL;
    
        if( path != NULL )
            free( path );
    
        path = (char *)malloc(13);
        if (path == 0)
    	printf("Memory allocation error.\n");
            
        strcpy(path, "NEWPATH=test");
    
        putenv(path);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need some help...
    By darkconvoy in forum C Programming
    Replies: 32
    Last Post: 04-29-2008, 03:33 PM
  2. which variable can store words?
    By Hunterofman in forum C++ Programming
    Replies: 8
    Last Post: 04-28-2008, 05:59 PM
  3. global and static variable in a class delivered in a DLL
    By George2 in forum C++ Programming
    Replies: 16
    Last Post: 04-13-2008, 08:19 AM
  4. Retrieving PATH Environment Variable
    By mercury529 in forum Windows Programming
    Replies: 9
    Last Post: 01-09-2007, 08:02 PM
  5. Replies: 2
    Last Post: 04-12-2004, 01:37 AM