CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Jan 2005
    Posts
    10

    Memory mgmt issue

    Hi all,

    I've got an apparently trivial issue. Consider the following snippet (compiled with gcc 4 on ubuntu breezer):
    Code:
    const char* f() {
      string s("foo bar");
      return s.c_str();
    }
    
    int main() {
      const char* c = f();
      cout << c << endl; //shouldn't it crash?
    }
    I expect the "cout << c" instruction to cause a run-time error, as string::c_str() does not allocate memory but returns a pointer to the string instance's internal data. This data should be destroyed along with s by the time f() terminates.

    I tried running the program through valgrind and still I got no errors. Eventually I tried on windows (vc++ 7.1) and rational purify finally reported an error.

    Any ideas as to why everything runs smoothly on linux? I know this can be due to freed blocks not being returned immediately etc. but is this not an incident waiting to happen?

    Thanks in advance

  2. #2
    Join Date
    Feb 2006
    Location
    London
    Posts
    238

    Re: Memory mgmt issue

    I could be wrong but it deems to me that returning of a local variable by CONSTANT pointer/reference extends its timelife until the current line of code is being executed.

    So if compiler does the following substitution:

    cout << f() << endl;

    then you have a perfectly valid statement.

  3. #3
    Join Date
    Jan 2001
    Posts
    588

    Re: Memory mgmt issue

    I think that the thing you're talking about only applies to const references, not just pointers. At best, I think you're looking at undefined behavior. So, depending upon your platform/compiler, it could work, not work, cause your computer to explode, etc.

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Memory mgmt issue

    Quote Originally Posted by abcd_68
    Hi all,

    I've got an apparently trivial issue. Consider the following snippet (compiled with gcc 4 on ubuntu breezer):
    Code:
    const char* f() {
      string s("foo bar");
      return s.c_str();
    }
    
    int main() {
      const char* c = f();
      cout << c << endl; //shouldn't it crash?
    }
    I expect the "cout << c" instruction to cause a run-time error,
    Crashes are not guaranteed to be produced, no matter how disastrous or horrid the code may be. That being said, the code you have produces undefined behavior.
    Any ideas as to why everything runs smoothly on linux?
    No, it isn't the OS (Linux). It is how the compiler has implemented (or not implemented) the underlying code to do this illegal behavior with pointers. You can just as easily get another brand of compiler that runs under Linux, compile your app, and the crash happens immediately.

    Regards,

    Paul McKenzie

  5. #5
    Join Date
    Dec 2005
    Posts
    642

    Re: Memory mgmt issue

    Quote Originally Posted by abcd_68
    Any ideas as to why everything runs smoothly on linux? I know this can be due to freed blocks not being returned immediately etc. but is this not an incident waiting to happen?
    When your program exhibits undefined hehavior, that means that anything could happen. You may get a compiler error, but may not. You may get a link error, but may not. You may get a run-time error with little or no memory corruption, but may not. You may get a run-time error with a lot of memory corruption, but may not. And finally, last, but not least, the program may.... gasp! .... work as expected!

    To understand what's going on, you need to know a little bit about the underlying implementation. f() returns a pointer to a block of memory that's been deallocated. When memory gets deallocated from the heap, it doesn't disappear. Most of the time, all that happens is that flags in a header preceding the memory block get set to indicate that the block is now free. The memory occupied by the block won't get stomped on until and if you allocate another piece of memory in the same place. So if you access the memory again soon, whatever you put there may still be there. In fact, only on rare occasions do the heap functions actually return memory to the operating system. This happens if either large contiguous chunks of the heap have been freed and the heap management routines have some kind of garbage collection, or more likely when your program exits. When the memory gets returned to the operating system, it really does disappear (at least on virtual-memory systems.) Well, the physical memory never actually disappears, but the OS unmaps it from your application's address space, so you don't see it anymore.
    Last edited by googler; February 23rd, 2006 at 04:22 PM.

  6. #6
    Join Date
    Jan 2005
    Posts
    10

    Re: Memory mgmt issue

    Thanks everyone for the answers but I'm afraid I didn't make myself clear enough.

    I know this program is wrong, that the freed memory is not literally freed etc. etc. (BTW I have to say that googler's disquisition should belong in an operating systems handbook as it's really clear and precise).

    My question (probably a bit OT) should have been: Why didn't valgrind catch the error? (this is what I meant by "running smoothly", my mistake). I even set --freelist-vol to a huge value but still the error went unreported. This seems a pretty trivial case of memory error so I thought it would be detected immediately. Purify on the contrary did catch it.

    Thanks again

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Memory mgmt issue

    Quote Originally Posted by abcd_68
    Why didn't valgrind catch the error?
    Maybe it has a bug or doesn't handle this type of construct correctly. Memory checking software isn't infallible. Why not give this example to the valgrind developers and have them figure it out.
    Purify on the contrary did catch it.
    No different than "why can software A do xxxx, while software B can't do xxxx?"

    Anyway, your example is simple enough -- there shouldn't have been a reliance on memory checking tools to give the thumbs up or down as to whether it is a bug or not. What memory checking tools should be used for are cases where the management of memory gets gnarly and obsfuscated, and it really isn't possible for a programmer to figure out the problem in a reasonable amount of time (due to code size or some other factors).

    Regards,

    Paul McKenzie

  8. #8
    Join Date
    Dec 2005
    Posts
    642

    Re: Memory mgmt issue

    Quote Originally Posted by abcd_68
    I know this program is wrong, that the freed memory is not literally freed etc. etc. (BTW I have to say that googler's disquisition should belong in an operating systems handbook as it's really clear and precise).
    Sorry for being overly pedantic, but there's an unrelated thread on virtual functions where someone asked why he's not getting a compiler error for doing something that's undefined in the standard, so I kind of lost it. Worse yet, there's also a situation there as well where the expected function ends up being called sometimes, even though the code is invalid, so people don't believe it's possible this is undefined behavior.

    As for valgrind - I guess you should demand your money back (or maybe it's "you get what you paid for" ?)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured