Potential memory leak and design considerations

This is a discussion on Potential memory leak and design considerations within the C++ Programming forums, part of the General Programming Boards category; Consider the following example: Code: #include <iostream> #include <stack> struct Foo{ Foo( int n ):num(n){} int num; }; class Bar{ ...

  1. #1
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391

    Potential memory leak and design considerations

    Consider the following example:
    Code:
    #include <iostream>
    #include <stack>
     
    struct Foo{ 
     Foo( int n ):num(n){}
     int num;
    };
     
    class Bar{
     
     public:
     
      Bar(){
       for( int i = 0; i < 10; i++ )
        stackOFoos.push( Foo(i) );
      }
     
      const Foo& takeAFoo(){
     Foo* afoo = &stackOFoos.top();
     stackOFoos.pop();
     return *afoo;
    }
     
      int howManyFoos(){ return stackOFoos.size(); }
     
     private:
      std::stack<Foo> stackOFoos;
    };
     
    int main(){
     
     Bar bar;
     std::cout << bar.howManyFoos() << "\n";
     
     Foo afoo = bar.takeAFoo();
     std::cout << bar.howManyFoos() << "\n";
     
     return 0;
    }
    1. Does the takeAFoo() function create a memory leak? Or is the foo& it returns bound to the scope of "afoo" in main, and since afoo isn't a pointer in main, no memory is leaked?

    2. Also, takeAFoo won't work if the function is declared const like this:
    Code:
    const Foo& takeAFoo() const{
       Foo* afoo = &stackOFoos.top();
       stackOFoos.pop();
       return *afoo;
      }
    Why is that?

    3. As a design consideration, I do want to be able to take a foo out of the bar class and do whatever I want with it. Is there a better way to go about achieving that kind of behavior?
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    1) I would suppose that
    Code:
    stackOFoos.pop();
    destructs the item you just took the pointer of. So you'll be returning an object that was just destructed. I think you will need to return a copy of top.

    2) That's because you are calling a non-const method on a member (pop). If you have a feeling that the operation should be constant and the popping of the stack shouldn't logically mean that you changing the Bar, you can make the stack mutable.

    3) Return the top by value I guess.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,307
    You can't do that.
    You're first taking the address of an item inside the stack, then you're deleting that item that the pointer was pointing to, then you're dereferencing that pointer to potentially garbage.
    If you want to pop an item off the stack you must receive it by value. You can't leak because it's all done by value. Dont worry, NRVO etc will probably kick in an eliminate the copy since library writers tend to be smart enough to do that.
    It wont compile if the function is declared const because it modifies its member variable through pop.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    Many thanks guys!

    2) That's because you are calling a non-const method on a member (pop). If you have a feeling that the operation should be constant and the popping of the stack shouldn't logically mean that you changing the Bar, you can make the stack mutable.
    So that means if I want to access inner elements of stacks, queues, etc, (and potentially make copies of those elements) I can do it if the stack is mutable, and I won't actually be modifying the original stack?
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  5. #5
    The larch
    Join Date
    May 2006
    Posts
    3,573
    If a member is mutable then the const-ness restriction of methods doesn't apply to this member.

    Don't get too excited over mutable though. You shouldn't use it just so you can change any non-const method into a const one.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Game Engine Development
    By MacGyver in forum Tech Board
    Replies: 15
    Last Post: 10-26-2007, 09:41 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21