0

I want to know if there is any way to tell if a function can safely delete an object passed as a parameter.

Code:

struct Test {

};

void f(Test *ptr) {
    delete ptr;   //if i delete the pointer here,
                  //i cannot use obj in main
}

int main() {
    Test *obj = new Test;

    f(new Test);
    f(obj);

    //delete obj;   //obj has already been deleted in f()
}

Is there any way to free the memory allocated by f(new Test), but keep the obj and still use it in main()?

Alex Gh
  • 55
  • 5
  • 1
    std::shared_ptr or another smart pointer, depending on the situation. However, you tagged c++98 so I assume you're not using modern c++? Generally passing a pointer and deleting in the callee would be considered bad practice. One would rather expect obj to be deallocated in main, where it has been allocated. But actually, raw allocation should be avoided and only if it's absolutely neccessary be used encapsulated into classes; E.g. do (de-) allocations within Test and make sure everything is deallocated in the destructor or sooner. – Gamification Jan 16 '19 at 20:23
  • 1
    You can't. You need to establish [ownership](https://stackoverflow.com/questions/49024982/what-is-ownership-of-resources-or-pointers) via rules and enforce those rules as best as you can. – user4581301 Jan 16 '19 at 20:32
  • Thank you for clarifying the use of raw pointers. Indeed this is c++98 (so no smart pointers). – Alex Gh Jan 16 '19 at 20:36
  • @Alex "*this is c++98 (so no smart pointers)*" - C++98 has the `std::auto_ptr` smart pointer. Or you can use smart pointers from the [Boost](https://www.boost.org/) library. – Remy Lebeau Jan 16 '19 at 20:53

2 Answers2

1

If you can move to C++11, you should use std::shared_ptr and your problem is solved. shared_ptr will take care about number of users of the pointer and will automatically clean it up when last user disposes it. And I strongly recommend transferring to modern C++, it solves great amount of problems.

You can also take a look at Boost SmartPtr - it does essentailly the same and can be used before C++11.

You could also try to implement such utility on your own, but you have to make sure to implement it properly - with reference counter incrementing and decrementing correctly in the spirit of Rule of Three


If you have to use raw pointers, then there's no way in standard C++ to guarantee that a pointer will (or will not) be deallocated by a function.
The only way to inform other programmers that your function wants to take ownership of the pointer (and will delete it) is via documentation, either in-code (with comments), or with a separate document (if you create an API for example).

However, you should strongly consider whether the function should take ownership of the pointer. Is it reasonable for function to own it? If not, just leave it and let allocating function take care of deallocation.

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
0

Actually you can do this in C++ 98. No need for the new standard. You do not place delete inside f. Instead just create the object you pass to f with auto_ptr guard:

Test *obj = new Test();

f(auto_ptr<Test>(new Test()).get());
f(obj);

Auto pointer will make sure the object is released after the function execution is over.

Well, to be honest it is *almost the same. If you explicitly need to delete the pointer inside f and not just to guard it to make sure it is released then you really need smart pointer and not just auto_ptr, for this you have to either use boost or c++11 or just write it yourself, it is really not complicated to implement.

Also pay attention that auto_ptr is deprecated in the new standard so this code is not forward compatible.

Yuri Nudelman
  • 2,874
  • 2
  • 17
  • 24
  • Thank you, I was not aware how auto_ptr works in c++98. Is it used for something else in modern c++, or is it just deprecated and not to be used? – Alex Gh Jan 17 '19 at 09:41
  • @AlexGh It's deprecated starting from C++11 and removed completely in C++17. `std::auto_ptr` is a little strange to use, and it cannot be used in standard containers for example. You can't store arrays with it either. – Yksisarvinen Jan 17 '19 at 11:10