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

  1. #16
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So, the correct solution, hidden in an overloaded function, would be:
    Code:
    std::string dirname(const std::string &fullname)
    {
         char *tmp = strdup(fullname.c_str());
         std::string result(dirname(tmp));
         free tmp;
         return result;
    }
    --
    Mats
    Last edited by matsp; 05-29-2008 at 03:22 AM. Reason: Add const correctness and reference on input.
    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.

  2. #17
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    No, this leaks if std::string's constructor throws. The correct solution is
    Code:
    vector<char> tmp(fullname.c_str(), fullname.c_str() + fullname.size() + 1);
    return std::string(dirname(&tmp[0]));
    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

  3. #18
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Alternatively (more for my own practice, really):
    Code:
    std::string dirname(const std::string &fullname)
    {
         char *tmp = strdup(fullname.c_str());
         try {
           std::string result;
           result = dirname(tmp);
         } 
         catch(...) 
         {
            free tmp;
            throw;
         }
         free(tmp);
         return result;
    }
    But it's a bit messy.

    --
    Mats
    Last edited by matsp; 05-29-2008 at 08:24 AM.
    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.

  4. #19
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    And your forgot to free the string in the non-error case.
    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

  5. #20
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I believe an auto_ptr may be in place?
    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. #21
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by CornedBee View Post
    And your forgot to free the string in the non-error case.
    Of course... :-(

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

  7. #22
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by Elysia View Post
    I believe an auto_ptr may be in place?
    It would apply delete to the malloced memory of strdup, so no. If anything, it would have to be
    Code:
    std::tr1::shared_ptr<char> tmp(strdup(input.c_str()), std::free);
    ... dirname(tmp.get())
    What's wrong with the vector, though?
    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

  8. #23
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I find the vector an even bigger hack, but one I'd prefer over mats's slightly longer code.
    The best solution would just be to have a function that returns a buffer, char* or wchar_t* from std::string, however. But once again we are not as lucky.
    I find it funny how the things in the standard library seems to be more oriented towards a C interface rather than a C++ interface (just look at the streams and how they only accept char* or wchar_t*), but with std::string, it's lacking a critical function for C compability.
    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.

  9. #24
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    I find the vector an even bigger hack, but one I'd prefer over mats's slightly longer code.
    The best solution would just be to have a function that returns a buffer, char* or wchar_t* from std::string, however. But once again we are not as lucky.
    I find it funny how the things in the standard library seems to be more oriented towards a C interface rather than a C++ interface (just look at the streams and how they only accept char* or wchar_t*), but with std::string, it's lacking a critical function for C compability.

    Or, we can do it this way:
    Code:
    std::string dirname(const std::string &fullname)
    {
         char tmp[MAX_PATH+1];
         strncpy(tmp, fullname.c_str(), MAX_PATH);
         tmp[MAX_PATH] = 0; // Make sure there is a zero somewhere!
         std::string result(dirname(tmp));
         return result;
    }
    Despite what you may think, this is better than strdup, since strdup will do strlen first, then strcpy, where this code only does strncpy(). It may take 4 or 8KB of stack-space, but it eliminates the need to allocate dynamic memory (and thus handle problems with freeing it).

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

  10. #25
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    And "taking 4k of stack space" in a near-leaf function such as this only means modifying the stack pointer, so yeah, that's a good way.

    Of course, MAX_PATH is Windows-only. There's a PATH_MAX in limits.h on POSIX.
    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

  11. #26
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by CornedBee View Post
    And "taking 4k of stack space" in a near-leaf function such as this only means modifying the stack pointer, so yeah, that's a good way.

    Of course, MAX_PATH is Windows-only. There's a PATH_MAX in limits.h on POSIX.
    Darn, I always get that one wrong.

    And yes, modifying the stack-pointer should be pretty fast - probably 5x faster than malloc.

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

  12. #27
    Registered User
    Join Date
    Oct 2001
    Posts
    2,129
    What's a near-leaf function?

  13. #28
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    A leaf function is one that calls no other functions. A near-leaf function was an on-the-spot word creation meaning a function that calls only leaf functions.
    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. #29
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by robwhit View Post
    What's a near-leaf function?
    It's a function that is near the "end" of a call-tree (main being the "root" of such a tree - at leas from the general programmers, as we don't normally consider the code that calls main() as part of the program, even if it technically is). A leaf-funciton is one that doesn't call any other functions, and a "near leaf" is one that only calls leaf-functions in itself. [Although, I suppose that the std::string::string(const char *) constructor is likely to call at least the new operator.

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

  15. #30
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    Here's a version that doesn't depend on strdup or the POSIX call:

    Code:
    std::string dirname(const std::string & path)
    {
        std::string dir = path.substr(0, path.find_last_of("/"));
    
        return ((dir != path) ? dir : std::string("."));
    }

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