简体   繁体   中英

How to know when to free memory?

So I'm running into a problem for a homework assignment- because getApple is const, I can't set locallyAllocated = false , which means whenever getApple is called with an apple instantiated and freed in some other program, my destructor attempts to free the memory and throws a double free error. What am I doing wrong, and how could I fix it? Note: the functions, their parameters and signatures have to be the way they are for our assignment. Thanks so much!

class poop
{

Apple localApple;
bool locallyAllocated;
void* pointer;

public:
    poop(const Apple &apple)
    {
        //Set our local apple to the apple in the provided address
        localApple = apple;
        locallyAllocated = false;
    }
    poop(string descr)
    {
        localApple.description = descr;
        pointer = maloc(sizeof(localApple);
        localApple.pointer = pointer
        locallyAllocated = true;
    }
    ~poop()
    {
        if(locallyAllocated)
        {
                //This throws a double free error if "getApple" is ever called
            free(pointer);
        }
    }
    void getApple(Apple* apple) const
    {
        if(apple)
        {
            //Copies our local apple into the address of the given apple
            //Because this function is "const", i can't do anything like set "locallyAllocated" to false
            *apple = localApple
        }
    }
}

You have some unsafe stuff going on here.. particularly:

poop(const Apple &apple)
{
    //Set our local apple to the apple in the provided address
    localApple = apple;
    locallyAllocated = false;
}

This means someone could probably free apple.pointer from under you, which means your localApple.pointer would be invalid. You should do the alloc in that method too and memcpy data around.

However, there's a bigger problem here... you're not actually even using .pointer . Do you even need to allocate anything? What is your intent of pointer?

If you're happy with your class as is, you should check out the mutable keyword.

By declaring locallyAllocated as mutable you will be able to change its value in const methods. Another worst solution would be to store locallyAllocated as a dynamically allocated boolean.

My first instinct is to advise you to use shared pointers

http://en.cppreference.com/w/cpp/memory/shared_ptr

However, if you do need to track the allocation yourself, you should make locallyAllocated mutable. In laymans terms, this means the member can be changed even in a method marked as const ( it allows you to maintain logical const while breaking 'physical' const ).

To me, your problem seems to be that several apples are supposed to share the same object, pointed to by Apple::pointer . This, however, is not made explicit in your code. That 's the problem.

There is not the ultimate rule for memory management that fits everywhere. However, there are ways to reflect your shared ownership of the object pointed to by Apple::pointer (I assume that's an apple, too, given its size?).

  • One thing you could do is write a proper copy constructor Apple::Apple(Apple const&) which takes care of duplicating the pointed to object.
  • If you want to keep the shared ownership, use an std::shared_ptr instead of a raw pointer. This will take the responsibility to delete the pointed to object off your shoulders. "The last to leave closes the door."

Note that your locallyAllocated member is a very simplified version of smart pointers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM