Check instance of struct member already created - c++

I'm currently stuck at a very specific problem. I have a map of structs like:
std::map<int, MyStruct> myMap;
typedef struct
{
long a;
int b;
MyObject* object;
} MyStruct;
On the structs creation object is always set to nullptr:
void createNewStruct(int id)
{
MyStruct newStruct{2L, 1, nullptr}; // create with no object
myMap.insert(std::pair(id, newStruct)); // store in map
}
I do this because I may have thousands of structs in the map, but only a few may need an actual "object" which itself is pretty large.
The object itself has a limited lifetime, and it should show if it's currently not shown, and not show if it's currently showing. If the end of the objects lifetime is reached it calls stopped(this):
void doShow(int id)
{
if(myMap[id].object == nullptr)
{
MyObject* newObject = new MyObject();
connect(object, SIGNAL(stopped(MyObject*), this, (objectStopped(MyObject*)); // create callback to delete object later
myMap[id].object = newObject;
// do something with object
}
}
Now if stopped(this) is called I try to clean up:
void objectStopped(MyObject* object)
{
// do something with object
delete object;
object = nullptr; //????
}
But obviously this is not working as intended because the check to nullptr won't ever be true again.
So what i want to achieve is: I have a map with a lot of structs, but only few of these structs need the object. How can I create and delete this object correctly?

If you have a C++11 compiler (which you should), you can make use of the id:
connect(object,
SIGNAL(stopped(MyObject*),
this,
[]() { delete myMap[id]; myMap[id] = nullptr; });

I think the best way to achieve this, is giving to MyStruct the ownership of MyObject, and not using external functions to manage that allocation.
If you do that, your design in general will improve.
For example you can give to MyStruct some functions to manage the creation of the MyObject structure: createObject() to create one, or destroyObject() to destroy it, a function to check if the object is present, and you can give to MyStruct his own doShow() member function, so your external doShow(int id) function will get the correct MyStruct for that specific 'id' and then will call MyStruct::doShow() nothing more.
When you destroy a MyStruct object, it will also deallocate its MyObject, if any, automatically, without worrying about it will callbacks, signal/slots mechanisms etc.
So, bottom line: I'd just make MyStruct object smarter, and giving to it the complete ownership of the MyObject class. I'm sure this will improve the overall design.

Related

Best practice to destroy class object from the thread started from this's objecs's method

So, so the title sounds mad, I think code will provide better understanding for my question
class Class
{
public:
static void* thread_func(void *thisObject)
{
// do some work
delete thisObject; // cleanup
}
start_thread()
{
auto worker = std::thread(thread_func, this);
worker.detach();
}
};
How to use this class
Class *p = new Class;
p->start_thread(); // start some work in parralel and return from function
So, I need to delete allocated object after thread_func is done. What is best way to implement such behaviour? Deleting thisObject from thread function as shown in the code sample works well, but looks as bad practice.
You can't really do that. For one thing, you haven't prevented anyone from stack-allocating an instance of your class. You could do that, but it may just lead to more issues.
Instead, make your thread function simply delete internal resources held in the class. But not the instance of the class. If you need to, you can split your class in two--one to manage deletion of the other which holds the real state.
As you are using c++11, use a lambda - then don't need to worry about anything..
class foo
{
public:
void run() {
// Do something..
}
};
int main(void) {
foo f;
// construct and run the thread...
auto t = std::thread([&f]() { f.run(); });
}
Allocation and deallocation shouldn't be the responsibility of two separate entities, worst in two separate threads. We like to see news and deletes in a symmetric way. Better then, you should use smart pointers:
class Class
{
static void* thread_func(std::shared_ptr<Class> self)
{
// do some work
}
public:
static void start_thread(std::shared_ptr<Class> self)
{
auto worker = std::thread(thread_func, self);
worker.detach();
}
};
How to use this class:
{
Class::start_thread(new Class);
}
Simply deleting object in worker thread is a bad idea, because your thread does not know how object was allocated: int could be created using new, by plcament new in malloced memory, by some allocator, on stack, in static memory, etc.
You can add a callback parameter to your thread_func. In your use-case you will simply pass a fucntion which deletes object. But if the need arises, you can pass fucntions doing anything you want.
I think this is a good place to use std::shared_ptr and in the scope where you are creating the object, use a std::weak_ptr.
http://en.cppreference.com/w/cpp/memory/weak_ptr

What is the object owner referred to in the Google C++ Style Guide?

The Google Style Guide for C++ says, in the section about smart pointers:
We prefer designs in which objects have single, fixed owners.
I don't fully understand the sentence.
What is the object owner?
Is it just the pointer?
The 'owner' of an object is not an actual part of the C++ language, but rather a conceptual tool - the idea being the 'owner' is in charge of deciding when the object can be destroyed. If an object has a single owner, it's easy to figure out when the object needs to be destroyed - just look at the owner. When an object is referenced by multiple other objects, however, things are less clear - none of the referring objects can, on its own, delete the referee object, as this would cause problems for the other referers. So there there is no "single, fixed owner".
To give some examples, consider a 'picture' object.
class Picture {
char *rawData;
public:
Picture(char *rawData_) : rawData(rawData_) { }
Picture(const Picture &p) : rawData(p.rawData) { }
};
Picture does not own rawData; as we can see from the copy constructor, it's all too easy to have multiple Pictures referencing the same data. A better version might look like:
class Picture {
std::vector<char> rawData;
public:
Picture(const std::vector<char> &rawData_) : rawData(rawData_) { }
};
This is similar, but now vector is hiding the raw pointer for us; it's impossible to have two Pictures reference the same pointer. And we take care of destroying the rawData array when the Picture is destroyed. In this case, the Picture owns the raw data.
Now, you don't have to use STL containers to have an owned object. You could do it manually:
class Picture {
size_t rawDataSize;
char *rawData;
public:
Picture(size_t rds, char *rd) {
rawDataSize = rds;
rawData = new char[rds];
memcpy(rawData, rd, rds);
}
~Picture() { delete [] rawData; }
Picture(const Picture &pic) {
rawDataSize = pic.rawDataSize;
rawData = new char[rawDataSize];
memcpy(rawData, pic.rawData, rawDataSize);
}
Picture& operator=(const Picture &pic) {
delete [] rawData;
rawDataSize = pic.rawDataSize;
rawData = new char[rawDataSize];
memcpy(rawData, pic.rawData, rawDataSize);
return *this;
}
};
This is also an owning relationship; the rawData array 'belongs' to the picture object, permanently. All accesses go through the picture object, and it's destroyed along with the picture object.
In general, with owning relationships, it's recommended to use wrapper classes to automate destruction, and prevent accidental copying. In my third example, had I forgotten the copy constructor or operator=, for example, terrible things would happen. Using wrapper classes like std::unique_ptr, boost::scoped_ptr/boost::scoped_array, or std::vector (for owned arrays) help prevent you from making mistakes.
Following bdonlan's answer, a C++ example:
int main()
{
// owner of 'obj' is main()
Object *obj = new Object;
// even if 'foo' receives an object, it is not its owner;
// it shouldn't be responsible for destroying it
foo(obj);
// obj is still alive
obj->DoSomething();
// the owner should clean up what it created
delete obj;
}
You asked,
In c++, how it is implemented. Is it just pointer to the object?
Often it will be a pointer but not always. As bdonlan said, ownership is a concept that the owner of an object will be in charge of cleaning up afterwards. An example with reference:
void foo(Object &obj) {}
int main()
{
// owner of 'obj' is main()
Object obj;
obj.Init();
foo(obj);
// the owner is responsible for calling Cleanup()
// it would be unnatural and confusing if Cleanup()
// was called in foo(), which is not the owner
obj.Cleanup();
}

can a pointer be deleted several times c++?

If I have the following example:
test.h
class MyClass
{
public:
MyClass();
std::string name1;
std::string name2;
std::string type1;
std::string type2;
void method1(MyClass &obj1);
void method2(MyClass &obj2);
}
test.cpp
MyClass *mainObject = new MyClass();
MyClass::MyClass()
{
}
void MyClass::method1((MyClass &obj1)
{
//do stuff
mainObject=&obj1; //we populate some of the MyClass variables
}
void MyClass::method2((MyClass &obj2)
{
//do stuff
mainObject=&obj2; //we populate the rest of MyClass variables
}
When should I delete mainObject inside test.cpp? Should I create a destructor in order for the client to delete it?
This is a good example that's best solved by not thinking about it yourself.
Use a shared_ptr<MyClass> mainObject; (either the new C++11 or the Boost version). It will do the delete for you.
Mind you, method1() and method2() should take their argument by shared_ptr too. Currently, they're doing a very bad thing: deleting an object that's passed by reference.
Deleting a pointer variable (pointing to non-0) several times is worse than not deleting it. Because the former can cause hard to find bugs and undefined behavior.
Your code is not correctly written. You should delete mainObject; as soon as you try to assign it with &obj1 or &obj2. But make sure that you do it only first time. Don't delete the pointer if it's pointing to obj1 or obj2.
I feel from this question and previous question of yours, that you are coming from Java/C# background. Better to read a good book on C++ first, you will learn that most of the time you don't need new/delete.
You should delete the pointer when you are done using the object it points to. You should not delete a pointer twice while it is pointing to a single object. You should not delete a pointer if it is pointing to an object that you didn't dynamically allocate with new.
I think that I'd go a slightly different way.
Like this:
test.h
class MyClass
{
public:
MyClass();
std::string name1;
std::string name2;
std::string type1;
std::string type2;
void method1(MyClass &obj1);
void method2(MyClass &obj2);
}
test.cpp
MyClass mainObject; // default c-tor called automatically.
MyClass::MyClass()
{
}
void MyClass::method1(MyClass & obj1)
{
//do stuff
//we populate some of the MyClass variables
mainObject.name1=obj1.name1;
mainObject.type1=obj2.type1;
}
void MyClass::method2(MyClass & obj2)
{
//do stuff
//we populate more of the MyClass variables
mainObject.name2=obj1.name2;
mainObject.type2=obj2.type2;
}
There is no simple way to only populate part of your object without specifying which parts.
But, otherwise, if you don't make mainObject a pointer then you don't need to allocate space for it, that's done automatically. (But, I should object to use of globals unless they are REALLY needed!)
This implementation of what I THINK you're trying to do will completely avoid the need for use of the heap, no need for new/delete.
There should always be a logical owner of any resource, and that owner should delete the resource.
There are cases where it makes sense to have shared ownership, and that is what boost::shared_ptr and similar solutions are for. The last one to give up ownership is then the one to delete the resource.
From all comments it looks like you might actually want the following:
static MyClass mainObject; // Not a pointer. Local to test.cpp
void MyClass::method1()
{
//do stuff
mainObject=*this; // Make a copy of the last object modified.
}
void MyClass::method2()
{
//do stuff
mainObject=*this; // Make a copy of the last object modified.
}
In this way, whether you call foo.method1() or bar.method2, the object on the left side of the . is copied to mainObject. No pointer funkyness needed at all, no new and no delete.
When should I delete mainObject inside test.cpp?
When it is no longer used.
Should I create a destructor in order for the client to delete it?
You only have to create a destructor if some resources of class MyClass have to be released - this is not the case with the shown code. The one you should release (=delete) is mainObject. But anyway, method1(..) and method2(..) are overwriting the mainObject pointer which leads to a dangling pointer (you can't reach the object anymore).
[EDIT]
To answer your question:
can a pointer be deleted several times c++?
Pointers are typically not allocated with new - only the objects they pointing to.
If you mean "can delete be called several times on the same pointer?" the answer is no and would lead to UB. delete on a pointer which is zero is defined and legal.

deleting memory allocated in static function in C++

I have C++ class as follows
class anotherClass;
class myClass {
private:
myClass() {}
~myClass() {}
typedef std::map<string, anotherClass* > stringToClass;
static stringToClass s_stringToClass;
public:
static anotherClass* getStringToclass(string name);
};
in above class for getStringToClass defintion is as follows
anotherClass* myClass::getStringToClass(string name) {
stringToClass::iterator iter;
iter = s_stringToClass.find(name);
if(iter == s_stringToClass.end()) {
typedef stringToClass::value_type stringToClassPair;
anotherClass* pothClass = new anotherClass();
s_stringToClass.insert(stringToClassPair(name, pothClass));
return pothClass;
}
else {
return iter->second;
}
}
now my question is we are allocating memory in static function as defined above. How can we delete memory? Can we delete memory in destructor, as destructor is not static?
Thanks for the help.
The collection will automatically clean up but the pointers inside it will not be, so you really have 2 options:
Used a collection of shared_ptr which will get cleaned up
Use a collection that stores raw pointers but cleans them up
There are classes of the latter type in boost but not sure they have one for maps and I would go for the former.
I would modify the structure too so that instead of using a static function and a static map, I would have a class with a function and a map, and have a static (singleton) instance of that class.
Your function may also be modified to return a shared_ptr but it could still return a regular pointer as the item will remain in the map forever and thus you do not need to worry about it becoming invalidated.
And as it can never be NULL you can even return a reference.
typedef std::map<string, boost::shared_ptr<anotherClass> > stringToClass;
anotherClass& myClass::getStringToClass(string const& name)
{
boost::shared_ptr<anotherClass> & value = s_stringToClass[name];
if( !value )
{
value.reset( new anotherClass );
}
return *value;
}
You might consider making it thread-safe too.
If you store it in a static variable, I guess you need them till the end of the execution of your process... If not, then you need to add a method to clean this static variable by deleting each element and call it when you don't need it anymore.
You should not do it in the destructor as the static variable is not linked to your class instances.
I'd use some kind of smart pointer such as the ones provided by Boost instead of raw pointers.
Yes, you can delete static variables in the destructor.
That being said, it's not a very good idea. What if you have two instances of your class, both using the static variable, and one gets destroyed? Its destructor would delete the memory, causing problems for the remaining instance of your class.
In addition to your odd usage of static members, it would be wiser to use smart pointers.
I think in your case, the destructor won't help, because there is no any object of MyClass.
I propose three ways
1. Don't store pointer, store the object itself.
2. Put the delete function into atexit; In your case
class MyClass
{
.....//Your already existing code
static void Destroy()
{
//iterate s_StringToClass and delete them
}
static void getStringToClass( string name )
{
struct DestroySetter
{
DestroySetter()
{
atexit( MyClass::Destroy );
}
};
static DestroySetter setter; //Setup the destoyer
//Your existing code here
}
3. Use smart pointer to manage the resource, shared_ptr is recommended.
Though I put a lot in second way, I suggest the 3rd way.
Problem one:
Functions should never return pointers (unless you really really really have too).
In this case you don't.
A returned pointer has no ownership semantics so it is not clear who the owner of the pointer is (if you don't know who owns the pointer then you don;t know who is reponsable for deleting it).
So either return a refernce or a smart pointer.
In this case a reference. As all the dynamically created objects are being maintained locally.
Since you are obviously new to this. Use a boost::shared_pointer. Technically this is probably not the best one for this situation, but it is the easiest one to just use when learning. I would have a look at the other smart pointers that are available and learn when it is appropriate to use each one.
class anotherClass;
class myClass
{
private:
myClass() {}
~myClass() {}
typedef boost::ptr_map<string, anotherClass > stringToClass;
// ^^^ Note: Not std:: you are not allowed to add class to std::
static stringToClass s_stringToClass;
// Ownership now maintained by the map automatically.
public:
// Return a reference.
// We retain ownership inside this class
static anotherClass& getStringToclass(string name);
};
Code:
anotherClass& myClass::getStringToClass(string name)
{
stringToClass::iterator iter;
iter = s_stringToClass.find(name);
if(iter == s_stringToClass.end())
{
s_stringToClass[name] = new anotherClass();
return s_stringToClass[name];
}
else
{
return iter->second;
}
}

Why doesn't shared_ptr have a virtual descructor? (and how can I get around this?)

I wanted to make a special version of shared_ptr that would perform specific operations when it was created or destroyed, but my plans appear to be foiled by the realization that shared_ptr's destructor is non virtual, meaning when I override it, my pointers never get cleaned up when the last instance of them are destroyed.
The only alternative that comes to mind is to build in this behavior into every class that I want to use with my hypothetical custom shared_ptr, and that's not feasible (or possible in some cases).
Edit:
The reason I want this is because I want to use some classes as userdata objects in lua, and I want each one of my objects that I use this way to have a fenv table unique to it that will be cleaned up when all references to the object have been removed. I plan on using the address of the pointer as they key into a table that holds the fenv table.
Lets say I have a widget that can have other widgets as children. I create two widgets in Lua, then set one as the child of the other and remove all lua references to the child widget (the fact that it's a child is handled in C++). The GC can now run at any time and remove the child. I don't necessarily want the child to have it's destructor run though, so I want to make it a shared_ptr. That way, C++ objects can still use it after Lua has cleaned it up. If I've assigned values or functions to it's fenv I still want to be able to access them. Only when the final reference to my child widget is removed do I want the fenv tabled to be removed totally.
It already has this ability built in without the need to let people do dangerous things like derive from it:
#include <boost/shared_ptr.hpp>
#include <iostream>
/*
* Done as a function for simplicity.
* But this can be done in so many ways
*/
void MyCleanup(int* x)
{
std::cout << "DONE\n";
delete x;
}
int main()
{
boost::shared_ptr<int> x(new int(5), MyCleanup);
}
Problem with deriving:
Just off the top of my head.
class X: public shared_ptr<int> { /* STUFF. With a special destructor. */ };
int main()
{
/* what happens now? Similar to slicing but not quite */
X data1(new int(5));
shared_ptr<int> data2;
shared_ptr<int> data3(data);
data2 = data1;
}
Just make a wrapper object; much easier. You can have the wrapper object have a shared_ptr instance inside it, and still use the allocation address of the internal object as an index. This seems much better than mucking around with derivation or custom cleanup routines, unless I'm missing something.
Eg:
class CWrapsLuaObject
{
CWrapsLuaObject( LuaObject* pObject )
{ [assign internal ptr, do mapping, etc.] }
shared_ptr< LuaObject > m_spObject;
[...]
};
shared_ptr< CWrapsLuaObject > spInstance( new CWrapsLuaObject( pObject ) );
Am I missing why this would not be the easiest solution (not taking anything away from the other suggested solutions, which could also work)?
You can provide a custom deletion object to be used with the shared_ptr. If you're trying to stick extra information into the shared_ptr, you may be better putting it into the deletion object. It doesn't feel very clean to me, but it works.
class ExtraThingToDestroy
{
public:
~ExtraThingToDestroy() { std::cout<<"Destroying the extra thing"<<std::endl; }
};
template<typename T>
class CustomDestructor
{
public:
CustomDestructor( ExtraThingToDestroy * v ) : v_(v) {}
void operator()( T* t ) { delete t; delete v_; }
ExtraThingToDestroy * v_;
};
main()
{
shared_ptr<int> ptr( new int, MyExtraDestructor<int>( new ExtraThingToDestroy ) );
shared_ptr<int> ptr2 = ptr;
//Now when ptr and all its copies get destroyed,
// the ExtraThingToDestroy will get deleted along with the int.
}
if you derive the class your_shared_ptr from shared_ptr and override the destructor, your destructor should be called in code like this:
{
your_shared_ptr<int> x(new int);
}
If you use it like this, instead:
{
shared_ptr<int>* ptrptr = new your_shared_ptr<int>(new int);
}
then it won't, but do you really need that?
Or am I misunderstanding something?