Thread: Is there a memory leakage in this simple code snippet

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    284

    Is there a memory leakage in this simple code snippet

    does strdup cause memory leakage?

    Code:
        string str("/usr/bin/");                                                                                                                                                 
        string str2 = string(dirname(strdup(str.c_str())));                                                                                                                    
        cout<<str2<<endl;
    I modified the code as:

    Code:
        string str("/usr/bin/");                                     
        char * tmp = strdup(str.c_str());                                                                                                                                        
        string str2 = string(dirname( tmp ));                                                                                                                                    
        delete(tmp);
    Using valgrind it reports:

    ==18859== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from 1)
    ==18859== malloc/free: in use at exit: 0 bytes in 0 blocks.
    ==18859== malloc/free: 3 allocs, 3 frees, 49 bytes allocated.
    ==18859== For counts of detected errors, rerun with: -v
    ==18859== No malloc'd blocks -- no leaks are possible.

  2. #2
    Registered User
    Join Date
    Jul 2006
    Posts
    162
    try 'string(dirname( *tmp ));' instead ?

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    strdup is nonstandard, I think, and use free, not delete.

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The first example is a memory leak, as you never free the result of strdup.

    In the second code-snippet, strdup uses malloc, so you should use free to free that memory.

    Also, there is absolutely no need to copy the string with strdup before calling dirname, as dirname has a local static variable that it returns as the result - and std::string will copy the string itself. However, If you are using multiple threads that may call dirname, you will need to make sure that the result from dirname is copied whilst in a lock situation.

    --
    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.

  5. #5
    Registered User
    Join Date
    Apr 2007
    Posts
    284
    No, as a matter of fact, you have to use strdup here.
    If your code is:

    Code:
    string str2 = string(dirname(str.c_str()));
    You will get errors from compiler:
    main.cc: In function `int main(int, char**)':
    main.cc:25: error: invalid conversion from `const char*' to `char*'
    Quote Originally Posted by matsp View Post
    The first example is a memory leak, as you never free the result of strdup.

    In the second code-snippet, strdup uses malloc, so you should use free to free that memory.

    Also, there is absolutely no need to copy the string with strdup before calling dirname, as dirname has a local static variable that it returns as the result - and std::string will copy the string itself. However, If you are using multiple threads that may call dirname, you will need to make sure that the result from dirname is copied whilst in a lock situation.

    --
    Mats

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Perhaps you could use this to avoid worrying about the free/delete:
    Code:
        string str("/usr/bin/");
        string str2 = string(dirname( &(std::vector<char>(str.begin(), str.end()))[0] ));

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    How about just
    Code:
    string str2 = string( const_cast<char*>(dirname( str.c_str() )) );
    EDIT: Bad suggestion.
    Last edited by Elysia; 05-29-2008 at 12:55 AM.
    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.

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by Elysia View Post
    How about just
    Code:
    string str2 = string( const_cast<char*>(dirname( str.c_str() )) );
    No, dirname() is actually allowed to modify the parameter, not just legacy const-incorrect.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Elysia, I do not think your example is correct, since the const_cast is applied to the return value of dirname(), but of course there is no need to do that. The const_cast should be applied to the argument to dirname(), but then the assumption is that dirname() does not modify its argument.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I need a prototype for dirname, since obviously std::string should be able to accept any string passed to it.
    Dang. No prototype for dirname >_<
    Then it's beyond me why you have to use such pesky workarounds.
    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.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I need a prototype for dirname, since obviously std::string should be able to accept any string passed to it.
    Dang. No prototype for dirname >_<
    RTFM: dirname
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Funny how just useless results showed up on google...
    But I see the problem.
    OK, so wouldn't this work then?
    Code:
        string str("/usr/bin/");
        string str2 = std::string( dirname(&str.begin()[0]) );
    Last edited by Elysia; 05-29-2008 at 01:00 AM.
    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.

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    OK, so wouldn't this work then?
    No, you're not allowed to rely on &str[0] or even &str.begin()[0] being continuous memory, or being in a plain format that is safe to modify.

    Funny how just useless results showed up on google...
    When I typed "man dirname", laserlight's suggestion was the first result.
    When I typed just "dirname", the third result was the specification of dirname from the OpenGroup. (They don't actually spell it out that the function may modify the input.)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Naturally the stupid std::string doesn't even have a function to access its buffer without a lot of hacks or workarounds.
    So much for flexibility of the standard library.
    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.

  15. #15
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It's a rule that's there so that the implementors have flexibility.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Mutex and Shared Memory Segment Questions.
    By MadDog in forum Linux Programming
    Replies: 14
    Last Post: 06-20-2010, 04:04 AM
  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. Memory leak by simple char
    By Ktulu in forum C++ Programming
    Replies: 42
    Last Post: 11-05-2006, 01:59 PM
  4. Replies: 14
    Last Post: 11-23-2005, 08:53 AM
  5. Very simple question, problem in my Code.
    By Vber in forum C Programming
    Replies: 7
    Last Post: 11-16-2002, 03:57 PM