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.
Related
I have a question about good C++ style:
I would like to write a class "MyClass" which has one or some pointers as members and MyClass is able to allocate memory to this pointers. I would like to use the implicit give default-copy-constructor (as well as the default-assignement-operator) to copy an instance of MyClass, so that only the pointers were copied and the new object share the data which the initial object has allocated.
My idea was to prohibit copied objects (created with copy constructor or assignment operator) to release memory (as well as allocate memory to member pointers). In order to distinguesh between copied objects and original objects (created by the constructor), I want to use the following code:
class MyClass
{
public:
MyClass(): originalPtr(this) { data = new char[100000]; }
~MyClass() { if(originalPtr == this) delete[] data; }
private:
MyClass *originalPtr;
char *data; // shared data (not copiable)
char otherFeatures[10]; // individual data (copiable)
};
Would this solution (using the comparison with the this-pointer) a good style for such a purpose (e.g. parsing an object by call by value) or is it risky? Of course, I assume that the original object live always longer than the copied objects.
Thank you!
No, this is a bad idea. If the pointers are shared by several instances, than the one to deallocate should be the last one to die, not the original one. This differs in the sense that the original one might not be the one to die, which would cause all others to be pointing at garbage. Even though you assume that it's the last one to die, you need to realise that the inner workings of a class should not rely on external assumptions. That is, the class has no guarantees on how its life span is managed by the rest of the implementation, so it shouldn't make assumptions.
In this situation you should track references to your data. The basic idea is to keep track of how many copies of the class you have. As soon as that count reaches zero, you are free to release that memory; the last copy has just died. Fortunately for you, STL already provides such an implementation. These are known as Smart Pointers. There are others, such as std::unique_ptr, which makes the opposite by ensuring that the data is owned only by a single instance.
Ok, assuming the general case, where the original object does not die at last. I like the idea to just count the instances. For example one could use such a concept:
class MyClass
{
public:
MyClass(): countOfInstances(new int())
{
++*countOfInstances;
data = new char[100000];
}
~MyClass()
{
--*countOfInstances;
if(!countOfInstances)
{
delete[] data;
delete countOfInstances;
}
}
MyClass(const MyClass &other) // analogous for the assignment operator
{
countOfInstances = other.countOfInstances;
data = other.data;
otherFeatures = other.otherFeatures;
++*countOfInstances;
}
private:
int *countOfInstances;
char *data; // shared data (not copiable)
char otherFeatures; // individual data (copiable)
};
Here, one should also make sure that the shared memory is completely allocated before allowing to make copies.
I'm new to the C++ world, but I have some experience with C and read some tutorials about C++.
Now, creating objects in C++ seems quite easy and works well for me as long as the class has only attributes that are values (not pointers).
Now, when I try to create objects which allocate memory in the constructor for some of their attributes, I figure out how exactly such objects are passed between functions.
A simple example of such class would be:
class A {
int *a;
public:
A(int value) {
this->a = new int;
*(this->a) = value;
}
~A() {
delete this->a;
}
int getValue() const { return this->a; }
}
I want to use the class and pass it by value to other functions, etc. At least these examples must work without creating memory leaks or double free errors.
A f1() {
// some function that returns A
A value(5);
// ...
return value;
}
void f2(A a) {
// takes A as a parameter
// ...
}
A a = f1();
A b = a;
f2(a);
f2(f1());
The class A is incomplete because I should override operator= and A(A& oldValue) to solve some of these problems.
As I understand it, the default implementation of these methods just copy the value of the members which is causing the destructor to be called twice on the same pointer values.
Am I right and what else am I missing?
In addition, do you know any good tutorial that explains this issue?
Use containers and smart pointers.
E.g. std::vector for dynamic length array, or boost::shared_ptr for dynamically allocated single object.
Don't deal directly with object lifetime management.
Cheers & hth.,
When you pass an object like that, you will create a copy of the object. To avoid doing that, you should pass a const reference...
void f2(A const & a)
{
}
This does mean that you are not allowed to change 'a' in your function - but, to be honest, you shouldn't be doing that anyways, as any changes won't be reflected back to the original parameter that was passed in. So, here the compiler is helping you out, but not compiling when you would have made a hard to find error.
Specifically, you must implement a copy constructor that properly copies the memory pointer for the a variable. Any default constructor would simply copy the memory location for the a variable, which would obviously be subject to a double-delete.
Even doing this:
A value(5);
// ...
return value;
won't work because when A falls out of scope (at the end of the section) the delete operator for A will be called, thus deleting the a sub-variable and making the memory invalid.
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;
}
}
EDIT: I know in this case, if it were an actual class i would be better off not putting the string on the heap. However, this is just a sample code to make sure i understand the theory. The actual code is going to be a red black tree, with all the nodes stored on the heap.
I want to make sure i have these basic ideas correct before moving on (I am coming from a Java/Python background). I have been searching the net, but haven't found a concrete answer to this question yet.
When you reassign a pointer to a new object, do you have to call delete on the old object first to avoid a memory leak? My intuition is telling me yes, but i want a concrete answer before moving on.
For example, let say you had a class that stored a pointer to a string
class MyClass
{
private:
std::string *str;
public:
MyClass (const std::string &_str)
{
str=new std::string(_str);
}
void ChangeString(const std::string &_str)
{
// I am wondering if this is correct?
delete str;
str = new std::string(_str)
/*
* or could you simply do it like:
* str = _str;
*/
}
....
In the ChangeString method, which would be correct?
I think i am getting hung up on if you dont use the new keyword for the second way, it will still compile and run like you expected. Does this just overwrite the data that this pointer points to? Or does it do something else?
Any advice would be greatly appricated :D
If you must deallocate the old instance and create another one, you should first make sure that creating the new object succeeds:
void reset(const std::string& str)
{
std::string* tmp = new std::string(str);
delete m_str;
m_str = tmp;
}
If you call delete first, and then creating a new one throws an exception, then the class instance will be left with a dangling pointer. E.g, your destructor might end up attempting to delete the pointer again (undefined behavior).
You could also avoid that by setting the pointer to NULL in-between, but the above way is still better: if resetting fails, the object will keep its original value.
As to the question in the code comment.
*str = _str;
This would be the correct thing to do. It is normal string assignment.
str = &_str;
This would be assigning pointers and completely wrong. You would leak the string instance previously pointed to by str. Even worse, it is quite likely that the string passed to the function isn't allocated with new in the first place (you shouldn't be mixing pointers to dynamically allocated and automatic objects). Furthermore, you might be storing the address of a string object whose lifetime ends with the function call (if the const reference is bound to a temporary).
Why do you think you need to store a pointer to a string in your class? Pointers to C++ collections such as string are actually very rarely necessary. Your class should almost certainly look like:
class MyClass
{
private:
std::string str;
public:
MyClass (const std::string & astr) : str( astr )
{
}
void ChangeString(const std::string & astr)
{
str = astr;
}
....
};
Just pinpointing here, but
str = _str;
would not compile (you're trying to assign _str, which is the value of a string passed by reference, to str, which is the address of a string). If you wanted to do that, you would write :
str = &_str;
(and you would have to change either _str or str so that the constnest matches).
But then, as your intuition told you, you would have leaked the memory of whatever string object was already pointed to by str.
As pointed earlier, when you add a variable to a class in C++, you must think of whether the variable is owned by the object, or by something else.
If it is owned by the object, than you're probably better off with storing it as a value, and copying stuff around (but then you need to make sure that copies don't happen in your back).
It is is not owned, then you can store it as a pointer, and you don't necessarily need to copy things all the time.
Other people will explain this better than me, because I am not really confortable with it.
What I end up doing a lot is writing code like this :
class Foo {
private :
Bar & dep_bar_;
Baz & dep_baz_;
Bing * p_bing_;
public:
Foo(Bar & dep_bar, Baz & dep_baz) : dep_bar_(dep_bar), dep_baz_(dep_baz) {
p_bing = new Bing(...);
}
~Foo() {
delete p_bing;
}
That is, if an object depends on something in the 'Java' / 'Ioc' sense (the objects exists elsewhere, you're not creating it, and you only wants to call method on it), I would store the dependency as a reference, using dep_xxxx.
If I create the object, I would use a pointer, with a p_ prefix.
This is just to make the code more "immediate". Not sure it helps.
Just my 2c.
Good luck with the memory mgt, you're right that it is the tricky part comming from Java ; don't write code until you're confortable, or you're going to spend hours chasing segaults.
Hoping this helps !
The general rule in C++ is that for every object created with "new" there must be a "delete". Making sure that always happens in the hard part ;) Modern C++ programmers avoid creating memory on the heap (i.e. with "new") like the plague and use stack objects instead. Really consider whether you need to be using "new" in your code. It's rarely needed.
If you're coming from a background with garbage collected languages and find yourself really needing to use heap memory, I suggest using the boost shared pointers. You use them like this:
#include <boost/shared_ptr.hpp>
...
boost::shared_ptr<MyClass> myPointer = boost::shared_ptr<MyClass>(new MyClass());
myPointer has pretty much the same language semantics as a regular pointer, but shared_ptr uses reference counting to determine when delete the object it's referencing. It's basically do it yourself garbage collection. The docs are here: http://www.boost.org/doc/libs/1_42_0/libs/smart_ptr/smart_ptr.htm
I'll just write a class for you.
class A
{
Foo * foo; // private by default
public:
A(Foo * foo_): foo(foo_) {}
A(): foo(0) {} // in case you need a no-arguments ("default") constructor
A(const A &a):foo(new Foo(a.foo)) {} // this is tricky; explanation below
A& operator=(const &A a) { foo = new Foo(a.foo); return *this; }
void setFoo(Foo * foo_) { delete foo; foo = foo_; }
~A() { delete foo; }
}
For classes that hold resources like this, the copy constructor, assignment operator, and destructor are all necessary. The tricky part of the copy constructor and assignment operator is that you need to delete each Foo precisely once. If the copy constructor initializer had said :foo(a.foo), then that particular Foo would be deleted once when the object being initialized was destroyed and once when the object being initialized from (a) was destroyed.
The class, the way I've written it, needs to be documented as taking ownership of the Foo pointer it's being passed, because Foo * f = new Foo(); A a(f); delete f; will also cause double deletion.
Another way to do that would be to use Boost's smart pointers (which were the core of the next standard's smart pointers) and have boost::shared_ptr<Foo> foo; instead of Foo * f; in the class definition. In that case, the copy constructor should be A(const A &a):foo(a.foo) {}, since the smart pointer will take care of deleting the Foo when all the copies of the shared pointer pointing at it are destroyed. (There's problems you can get into here, too, particularly if you mix shared_ptr<>s with any other form of pointer, but if you stick to shared_ptr<> throughout you should be OK.)
Note: I'm writing this without running it through a compiler. I'm aiming for accuracy and good style (such as the use of initializers in constructors). If somebody finds a problem, please comment.
Three comments:
You need a destructor as well.
~MyClass()
{
delete str;
}
You really don't need to use heap allocated memory in this case. You could do the following:
class MyClass {
private:
std::string str;
public:
MyClass (const std::string &_str) {
str= _str;
}
void ChangeString(const std::string &_str) {
str = _str;
};
You can't do the commented out version. That would be a memory leak. Java takes care of that because it has garbage collection. C++ does not have that feature.
When you reassign a pointer to a new object, do you have to call delete on the old object first to avoid a memory leak? My intuition is telling me yes, but i want a concrete answer before moving on.
Yes. If it's a raw pointer, you must delete the old object first.
There are smart pointer classes that will do this for you when you assign a new value.
I have an interesting question about C++ pointers.
You probably will think that I have to change my design, and avoid
doing what I am doing, and you are probably right.
But let's assume that I have a good reason to do it my way.
So this is the situation. I have a C++ class TestClass, and I have a pointer A of this type:
TestClass* A = new TestClass();
Among other things TestClass has this function:
void TestClass::Foo(){
TestClass* B = new TestClass();
...
}
This function creates object B of the same type and populates it with some data.
At the end of this function, I want pointer A to point at object B.
Anywhere outside this function it would look like A=B; inside this function
it could look like this = B
But as you know you cannot reassign "this" pointer.
Possible solutions:
Copy the memory:
memcpy(this, B, sizeof(TestClass));
This method works correctly. The function copies each bit of object B into object A.
Problem: if TestClass is a big object(and it is), it creates significant overhead in performance for multiple Foo calls.
Return a B pointer from the function and do something like this
Temp = A;
A=A->Foo();
freeMemory(Temp);
But this code looks stupid, and it makes function Foo very hard to use.
So the question is, how I can do this = B from inside a member function, without copying whole objects?
Use an extra level of indirection. Your TestClass can have a pointer that points to a class that contains all of its data.
class TestClass
{
private:
TestClassData* m_data;
};
void TestClass::Foo()
{
TestClassData* B = new TestClassData();
...
delete m_data;
m_data = B;
}
Just make sure your operator== returns true if the contents of m_data are equal.
how i can do this = B
You cannot.
One of the working solutions:
memcpy(this, B, sizeof(TestClass));
this method working correctly.
If TestClass is not a POD, this function doesn't work. You can't memcpy objects with virtual functions, for example. You'll blow away the vtable.
Inside of your function, you can do
*this = B;
Which make pretty the same copy operation.
Or you could also declare
Foo(TestClass &X);
And reassign X address inside.
You can't. this is defined by the standard as a TestClass * const.
To realize why, think about this code:
int main() {
TestClass A;
A.Foo();
return 0;
}
A is on the stack. How do you make an object on the stack 'refer' to something else?
The problem is that many pointers, not just A, can point to the old object. The this pointer is not A, although A contains a copy of it. The only way to do it is 1. reassign A, or 2. make a new pointer type that adds a level of indirection to your object so you can replace it without anyone knowing.
What you are doing is not good.
First off, you have function Foo that will:
Create and generate a new class
Reassign an existing class to the new class
So, why not just change the existing class into the class you want?
That said, you could make Foo static and take "take this manually":
void Foo(TestClass*& this)
{
delete this;
this = // ...
}
But that's equally nasty as your other solutions. We probably need more context to give you the best solution.
I'm pretty sure that you should look at smart pointers as a way to solve this problem. These essentially add an extra level of indirection (without changing the syntax clients use), and would allow you so change the actual object pointed to without informing the client.