A question:
Should I delete pointers which are fetched in functions (not created, just fetched)? Example:
#include <SomeObject>
#define SAFE_DELETE(p) { if (p) { delete (p); (p) = NULL; } }
class DraftObject
{
public:
DraftObject() : _x(0) {}
~DraftObject(){}
int CalculateSomething()
{
AnotherObject* aObj = SomeObject::getInstance()->getAObjPointer();
/* Do some calculations and etc... */
_x += aObj->GetSomeIntValue();
SAFE_DELETE(aObj) // <-- Would you recomend this here?
return _x;
}
protected:
int _x;
};
The aObj would be re-used in other cases as well in the SomeObject instance. I could go on and always call SomeObject::getInstance()->getAObjPointer() for everything I need it for, but SomeObject::getInstance()->getAObjPointer()->GetSomeIntValue() is not as readable as aObj->GetSomeIntValue() in my personal opinion.
I know that I would not need to worry if I used something from boost (shared_ptr, weak_ptr or even auto_ptr), but I am more curious about the way this works. Will not deleting the pointer create a memory leak situation or will the deletion of the pointer delete it from the memory so that it will be gone in other scopes (the instance object as well as anywhere else it might be used) ?
Any thoughts?
Cheers.
It depends.
If SomeObject::getInstance()->getAObjPointer(); returns a different object each call, probably yes. Otherwise, no. This should be documented.
Also, your "safe delete":
#define SAFE_DELETE(p) { if (p) { delete (p); (p) = NULL; } }
is utterly useless. And ugly. If I saw this in code, I'd go and make fun of the programmer who wrote it. If p is NULL, the delete is safe.
No, do not use delete because that will deallocate the memory for the object and you will not be able to use it later.
It should be documented in the API.
Some libraries are returning pointers which SHOULD NOT be deleted by the users, because they are also kept in internal data structures. Others are creating pointers which should be deleted by the user.
Assuming that you have actually wrote yourself this class and function, you probably want to delete the pointer at the end of the function if you don't use use this instance anywhere else (including in internals functions).
Related
Say I have two classes inheriting from a common base, such as
class Thing{
public:
virtual void f()=0;
};
class Thing_variant_a: public Thing{
public:
void f(){
std::cout<<"I am (a)"<<std::endl;
}
};
class Thing_variant_b: public Thing{
public:
void f(){
std::cout<<"I am (b)"<<std::endl;
}
};
And a function taking a reference to a Thing object as an argument.
void function(Thing& t){
t.f();
}
Depending on conditions I would like to call function with either a thing_a or thing_b (and possibly extend this at some point adding another possibility of thing_c)
I know I can do this using a pointer
Thing *t = nullptr;
if(condition_a){
t = new Thing_variant_a();
} else if(condition_b){
t = new Thing_variant_b();
}
function(*t);
However, I would like to know if there is a better way, that
does not allocate heap memory
does not require me to take care of deleting t at some point (probably smart pointers, but I don't know much about those)
ensures I always pass a valid Thing reference to function (there might be more conditionals in a complicated structure than in this minimal example) I could do if(t){ function(*t);}else{/*handle error*/}), but it seems like there should be a more elegant solution.
If not all of the above are possible any combination of those?
This sounds very much like an XY problem. There is probably a different solution to your problem entirely.
C++ is a statically-typed language; that means types used in a given code path are fixed at compile-time. Dynamic types (types known at run time) are normally allocated via the heap or all-at-once and then selected at run time.
So not much is possible in your case as you've noticed..
You could for example just have two different code paths:
if (condition_a) {
Thing_variant_a a;
function(a);
} else if (condition_b) {
Thing_variant_a b;
function(b);
}
Preallocate the types:
Thing_variant_a a;
Thing_variant_a b;
if (condition_a) {
function(a);
} else if (condition_b) {
function(b);
}
Or use a template:
template<typename T>
void do_something() {
T t;
function(t);
}
// somewhere else in the code ...
do_something<Thing_variant_a>();
// or ...
do_something<Thing_variant_b>();
Here's a way using dynamic memory and unique_ptr:
std::unique_ptr<Thing> t;
if (condition_a) {
t = std::make_unique<Thing_variant_a>();
} else if (condition_b) {
t = std::make_unique<Thing_variant_b>();
}
function(*t);
// t is delete'd automatically at end of scope...
And by the way, a function like int f(){...} should return some int value.
Here is a way to do it without using the heap or pointers:
Thing_variant_a thingA;
Thing_variant_b thingB;
if(condition_a){
function(thingA);
} else if(condition_b){
function(thingB);
}
If you want, you reduce it to a single call via the ternary operator:
Thing_variant_a thingA;
Thing_variant_b thingB;
function(condition_a ? static_cast<Thing &>(thingA) : static_cast<Thing &>(thingB));
As far as references go, references in C++ are required to be always be non-NULL -- so if you try to dereference a NULL pointer (e.g. by calling function(*t) when t==NULL) you've already invoked undefined behavior and are doomed; there is nothing the code inside function() can do to save you. So if there is any change that your pointer is NULL, you must check for that before dereferencing it.
I'll try to answer each of your questions
does not allocate heap memory
Unfortunately c++ only supports polymorphism using pointers. I guess the problem you would face here is fragmented memory (meaning that your pointers are everywhere in the heap). The best way to handle that is to allocate the memory using a memory pool.
You could use an std::variant but you will still need to test for the currently available type in the variant.
does not require me to take care of deleting t at some point (probably smart pointers, but I don't know much about those)
You could use a std::unique_ptr which will basically called the destructor when no one holds that pointer anymore.
ensures I always pass a valid Thing reference to function (there might be more conditionals in a complicated structure than in this minimal example) I could do if(t){ function(*t);}else{/handle error/}), but it seems like there should be a more elegant solution.
If you use pointers your could just check for the nullptr as you are doing right now. I'm not sure what you are meaning by valid reference as a reference always points toward something and cannot be empty.
So to illustrate my question I have made an example:
#include <iostream>
using namespace std;
struct A
{
void doSomething (){
cout << "Something\n";
}
};
struct B
{
A a;
A *getA ()
{
return &a;
}
};
int
main ()
{
B *b = new B ();
A *a = b->getA ();
// POINT 1
if (nullptr != a)
{
a->doSomething ();
}
delete b;
b = nullptr;
// POINT 2
if (nullptr != a)
{
a->doSomething ();
}
return 0;
}
This compiles and runs without errors on my machine, but if you inspect the code, really there is a problem of a dangling pointer on the lines following the comment marked "POINT 2".
Since b was deleted, then a is now invalid (since it was deleted by dtor of b).
So I could use a shared pointer to remedy this, but that would keep the instance of a around even after b was deleted, and also I would not be able to allocate a on the stack. These are two things I want to avoid. Instead I simply want to know if a is still valid.
I could also have used a unique pointer but then I could only have one single instance of a which is not what I want either, I want many copies of the pointer to a.
So is there some existing pointer/reference type that would allow me to do this? Are there any reason why this is a good/bad idea?
You have just discovered the wonders of ownership semantics :)
How to solve this problem depends on the design of your application: what you need and what you are trying to achieve.
In this case, if you really want to share ownership of an object, use std::shared_ptr which keeps a reference count of how many pointers are left, so that the last deletes the object; possibly std::weak_ptr if you only need to check if the object is still alive but don't want to keep it alive longer than needed.
However, do note that (ab)using shared pointers may be a sign of a bad design.
By the way, your A a; member is not allocated in the stack (i.e. the title is wrong).
Only viable solution using standard library that come in mind is to use std::weak_ptr() - it will allow to check object validity without holding it's ownership. That comes with price - you have to maintain ownership of it with std::shared_ptr. Though it is possible to create std::shared_ptr to an object with automatic storage duration and noop deleter I would do that only if I really need that as such method is error prone and defeats the purpose of a smart pointer.
The best way is to not expose a.
Your B is the interface. Give it the functions you need to perform. Have it go on to invoke whatever it needs to invoke on the a in order to make that happen.
Then remove getA(), and make a private.
Now it's completely encapsulated and the calling scope cannot arse around with it like this!
No need for pointers or dynamic allocation; just good, old-fashioned OOP.
class Foo {
// some codes
}
class Bar {
// Constructor, Destructor
vector<Foo*> fooVector;
Foo* getFoo(long index)
{
return fooVector[index];
}
long addFoo(Foo* foo)
{
fooVector.push_back(foo);
return fooVector.size() - 1;
}
void removeFoo(long index)
{
delete fooVector[index];
}
}
This is my codes.
But I want to change removeFoo like
void removeFoo(long index)
{
Foo* foo = getFoo(index);
delete foo;
}
Is it right? I can't sure about this.
In my thought, It may delete foo variable.
Please tell me whether it is right or not.
If the memory for the pointer was allocated by new then yes that's how you free it. However, that won't remove the pointer from the vector, so afterwards your vector have an entry that no longer point to valid memory. You need to erase it from the vector.
Also note that in modern C++ there is seldom a need to use pointers anymore, except for polymorphism really. If you don't have pointers, you don't have to worry about freeing memory or stray pointers.
Using such method you are bypassing most of the benefits you gained from using vector. When removing elements by delete (which is valid in the case you described) you will rubbish your fooVector with non-valid data pointers to some undeclared/invalid memory areas.
It would be handy if, in addition, you showed us how you actually create fooVector elements.
In my opinion, both ways that you presented are valid in C++, but they will lead to hard-to-rely-on results and rubbish in your vector.
I'm looking for a way to ensure that an object that is executed on the heap is ALWAYS deallocated when I'm done with it.
I know that if it's allocated on the stack, I can use RAII to ensure it will be taken care of - unfortunately, this won't work for me (at least directly) because the object in question is actually created by calling an api function, which then returns a pointer to the object it creates on the heap.
So, conceptually, what I want to do is something like:
TheApi::ApiObject* p_myObj = TheApi::createAnApiObj();
try
{
doStuffWithMyObjThatMayError(p_myObj);
}
finally
{
delete p_myObj;
}
The only thing I can think of to do would be to make some sort of dummy cleanup class, and create an instance of that on the stack:
class MegaMaid
{
private:
TheApi::ApiObject* toFree;
public:
MegaMaid(TheApi::ApiObject* toFree)
{
this->toFree = toFree;
}
~MegaMaid()
{
delete toFree;
}
};
void doStuff()
{
TheApi::ApiObject* p_myObj = TheApi::createAnApiObj();
TheApi::ApiObject* p_myObj;
MegaMaid cleaner(p_myObj);
doStuffWithMyObjThatMayError(p_myObj);
}
Is there a better way to accomplish this? Or is this the accepted solution?
You can still use RAII on pointers returned by functions. You can use smart pointers (which is exactly what the dummy class you are describing is) like this:
std::unique_ptr<TheApi::ApiObject> p_myObj(TheApi::createAnApiObj());
That "dummy class" is known as "smart pointer". You should check out std::auto_ptr or boost::shared_ptr. They provide exactly what you look for.
Consider the following situation:
SomeType *sptr = someFunction();
// do sth with sptr
I am unaware of the internals of someFunction(). Its pretty obvious that the pointer to the object which someFunction() is returning must be either malloc'ed or be a static variable.
Now, I do something with sptr, and quit. clearly the object be still on the heap which is possibly a source of leak.
How do I avoid this?
EDIT:
Are references more safer than pointers.
Do the destructor for SomeType would be called if I do :
{
SomeType &sref = *sptr;
}
Any insights.
You need to read the documentation on someFunction. someFunction needs to clearly define the ownership of the returned pointer (does the caller own it and need to call delete or does someFunction own it and will make sure the the object is destructed sometime in the future).
If the code does not document it's behavior, there is no safe way to use it.
What do you mean by quit? End the process? Your heap is usually destroyed when the process is destroyed. You would only get a leak potential after quitting the process if your asked the operating system to do something for you (like get a file or window handle) and didn't release it.
Also, functions that return pointers need to document very well whose responsibility it is to deallocate the pointer target (if at all), otherwise, you can't know whether you need to delete it yourself or you could delete it by accident (a disaster if you were not meant to do so).
If the documentation of the function doesn't tell you what to do, check the library documentation - sometimes a whole library takes the same policy rather than documenting it in each and every function. If you can't find the answer anywhere, contact the author or give up on the library, since the potential for errors is not worth it, IMHO.
In my experience most functions that return a pointer either allocate it dynamically or return a pointer that is based on the input parameter. In this case, since there are no arguments, I would bet that it is allocated dynamically and you should delete it when you're done. But programming shouldn't be a guessing game.
It's always a good habit to clean up after yourself, don't presume the OS will do it;
There's a good change your IDE or debugger will report memory leak when you quit your application.
What do you have to do ? Well, it depends, but normally you have to release the memory allocated by someFunction(), and the documentation will probably help you with that, either there's an API to release the memory or you have to do it manually with free or delete.
Max
The library should document this.
Either you delete it explicitly after use or you call some release method which makes sure that object (and any other resources it points to*) doesn't leak.
(given a choice) Unless its a huge (in terms of memory) object, I would rather prefer a return by value. Or pass a reference to the function.
If someFunction returns an object for me it should be normal to have a pair function like someFunctionFree which you'll call to release the resources of the SomeType object. All the things needed should be found in the documentation of someFunction (mainly how the object can be freed or if the object is automatically freed). I personally prefer the corresponding deallocation function (a CreateObject/DestroyObject pair).
As others note it's up to the function to enforce it's ownership assumptions in code. Here's one way to do that using what's known as smart pointers:
#include <iostream>
#include <boost/shared_ptr.hpp>
struct Foo
{
Foo( int _x ) : x(_x) {}
~Foo() { std::cout << "Destructing a Foo with x=" << std::hex << x << "\n"; }
int x;
};
typedef boost::shared_ptr<Foo> FooHandle;
FooHandle makeFoo(int _x = 0xDEADBEEF) {
return FooHandle(new Foo(_x));
}
int main()
{
{
FooHandle fh = makeFoo();
}
std::cout<<"No memory leaks here!\n";
return 0;
}