CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 24
  1. #1
    Join Date
    Nov 2003
    Location
    Pasadena, CA
    Posts
    48

    Does the following statement invoke undefined behavior?

    The example uses built-in types but of course what I really care about are user-defined types.

    This is a question about evaluation rules... I believe it is well behaved because the rhs argument to operator= must be fully evaluated before the assignment occurs. But does the copy constructor complete before new returns?

    int
    main(void)
    {
    int * p1 = new int(3);

    // is this legal? (ignore the memory leak)
    p1 = new int(*p1); // clone

    return 0;
    }
    The views expressed are those of the author and do not reflect any position taken by the Goverment of the United States of America, National Aeronautics and Space Administration (NASA), Jet Propulsion Laboratory (JPL), or California Institute of Technology (CalTech)

  2. #2
    Join Date
    Feb 2003
    Location
    California
    Posts
    334
    I'm not an expert on the standards, but I'm pretty sure the constructor is supposed to complete before the assignment occurs.
    Henri Hein
    Principal Engineer, Propel
    Do not credit Propel with my views or opinions.

  3. #3
    Join Date
    Aug 2002
    Location
    United States
    Posts
    729
    aside from your note about the memory leak, yes that should work just fine so long as the copy constructor does in fact exist *you said you dont care about POD types*

  4. #4
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    AFAICT it's legal, but why would you want to do it? You can't ignore the memory leak...
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  5. #5
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401
    p1 = new int(*p1);
    is as legal as
    a = a+1;

    First the rhs of = is completely evaluated, then it is assigned to the lhs.

  6. #6
    Join Date
    Nov 2002
    Location
    Foggy California
    Posts
    1,245
    Originally posted by Graham
    You can't ignore the memory leak...
    Sure you can! I've seen many people ignore memory leaks! (Far too many!)

  7. #7
    Join Date
    Nov 2002
    Location
    Foggy California
    Posts
    1,245
    Before anyone jumps on me, I am not encouraging anyone to actually ignore memory leaks. I was more making a (hopefully ammusing) comment about how many applications I have seen that have (and ignore) memory leaks.

  8. #8
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470
    I understood it...
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  9. #9
    Join Date
    Feb 2003
    Location
    California
    Posts
    334
    Originally posted by Graham
    AFAICT it's legal, but why would you want to do it? You can't ignore the memory leak...
    I suspect the OP wants to do something of semantic importance in the c'tor. You could do something like this:


    Code:
    CFoo::CFoo(CFoo* pFoo)
    {
        DeepCopy(this, pFoo);
        delete pFoo;
    }
    Then you would not have a memory leak.

    Personally, I would not use or advocate this type of design, but it's legal and you can make it clean.
    Last edited by hankdane; January 23rd, 2004 at 06:20 PM.
    Henri Hein
    Principal Engineer, Propel
    Do not credit Propel with my views or opinions.

  10. #10
    Join Date
    Aug 2002
    Location
    United States
    Posts
    729
    i think we have done exactly what the OP was trying to make us not do by his statement "aside from the memory leak". in other words, he knows it's a memory leak and that issue is irrelevant for the scope of his other question and he simply didn't feel like typing the delete line.

  11. #11
    Join Date
    Sep 2002
    Location
    Maryland - Fear The Turtle!
    Posts
    7,537
    Originally posted by KevinHall
    Before anyone jumps on me, I am not encouraging anyone to actually ignore memory leaks. I was more making a (hopefully ammusing) comment about how many applications I have seen that have (and ignore) memory leaks.
    such a simple thing that causes so many problems....or maybe it's just simple developers...

    GDI object leaks, file handle leaks, new/delete, malloc/free, using API's that say you must call this when you are finished with the buffer to free it...and you don't...

    whats even more sad is when it happens in a product that's regulated by the FDA because it runs in hospitals...

    /Amused by your statement, not amused that it happens.

  12. #12
    Join Date
    Jun 2001
    Location
    Switzerland
    Posts
    4,443
    In fact, the second "new" is a placement new, if I am not mistaken, and it is not the cause of the memory leak per se, but rather the missing "delete" is. Or am I wrong?
    Gabriel, CodeGuru moderator

    Forever trusting who we are
    And nothing else matters
    - Metallica

    Learn about the advantages of std::vector.

  13. #13
    Join Date
    Aug 2002
    Location
    United States
    Posts
    729
    the second new call wouldn't be a problem per se if he saved the original pointer (p1) somewhere else so he could access (delete) it later. however, his code does not do this from what we see and immediately after the second new call there is a reserved chunk of space that he no longer has any means of accessing (the first new call) and thus, a memory leak. gabriel you are entirely right (like usual =) ) that the problem is simply a missing delete call on something that was allocated. but in this case the reason that the delete cant be called is because the 2nd new has changed p1 to point to something else so i guess it really just depends on how you look at it. a lack of a delete call or the new call itself can 'cause' the memory leak here depending on your point of view.

    buuuuut, i still think we have taken this way out of context though and the OP is aware of all the issues we are raising.
    Last edited by filthy_mcnasty; January 24th, 2004 at 04:55 AM.

  14. #14
    Join Date
    Jun 2001
    Location
    Switzerland
    Posts
    4,443
    Originally posted by filthy_mcnasty
    the second new call wouldn't be a problem per se if he saved the original pointer (p1) somewhere else so he could access (delete) it later. however, his code does not do this from what we see and immediately after the second new call there is a reserved chunk of space that he no longer has any means of accessing (the first new call) and thus, a memory leak. gabriel you are entirely right (like usual =) ) that the problem is simply a missing delete call on something that was allocated. but in this case the reason that the delete cant be called is because the 2nd new has changed p1 to point to something else so i guess it really just depends on how you look at it. a lack of a delete call or the new call itself can 'cause' the memory leak here depending on your point of view.

    buuuuut, i still think we have taken this way out of context though and the OP is aware of all the issues we are raising.
    The second new is a placement new, that is, it won't change the pointer value {p1 = new int(*p1); -- note that p1 is passed to new()}, so we won't have a memory block that we can't access (or delete) any more. The placement new is, of course, useles, for ints (or other PODs). In the general case, it would construct the object at the address passed to it.

    A delete p1 before the return eliminated the leak.
    Gabriel, CodeGuru moderator

    Forever trusting who we are
    And nothing else matters
    - Metallica

    Learn about the advantages of std::vector.

  15. #15
    Join Date
    Jun 2001
    Location
    Switzerland
    Posts
    4,443
    Dang! Forget what I said -- it's wrong. I haven't noticed the dereferencing of p1.
    Gabriel, CodeGuru moderator

    Forever trusting who we are
    And nothing else matters
    - Metallica

    Learn about the advantages of std::vector.

Page 1 of 2 12 LastLast

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