This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why does the use of ‘new’ cause memory leaks?
What is the difference between (if there is one):
Player player=*(new Player());
and:
Player &player=*(new Player());
Both (seem to) behave the same way, but I surely miss something?!?
The difference is that the first makes a copy, whereas the second creates a reference to the object pointed to by the pointer returned by new Player().
Player player=*(new Player());
copy-initializes player using the copy-constructor.
Player &player=*(new Player());
just creates an alias for *(new Player()), which is valid because new Player() isn't a temporary. Player& player = Player() would be illegal because of that.
They're the same in that they both suck.
new Player() is an expression that creates an object (unnamed) on the so-called heap. The result of the expression is a pointer to the newly created object. Now when you do
Player player = *(new Player())
you define a variable named player that is a copy of the newly created object. Moreover, you've lost all handles (access) to the heap object, and you can never free the memory it occupies.
On the other hand,
Player &player=*(new Player());
creates a reference named player to the newly created object. Thus, you have access to that object. In particular, you can free the memory and destroy that object by
delete &player;
Related
This question already has answers here:
Why should C++ programmers minimize use of 'new'?
(19 answers)
Closed 5 years ago.
Lets say we have this..
class MyClass
{
int value;
void addIntToObject(int num)
{
value = num;
}
}
MyClass *object = new MyClass();
object->addIntToObject(1);
object->addIntToObject(2);
Now let's say we do this again...
object = new MyClass();
By using new twice on the same object, does that mean we have deleted all data that was stored in object? can someone explain to me the exact workings of using new twice on the same object
Would this be an efficient way to free memory? (like using delete and delete[])
You didn't "do new twice on the same object". The new expression creates an object. By doing new twice you made two entirely separate objects.
The variable object is a pointer. It points to other objects. The = operator on a pointer means to change which object the pointer is pointing to.
So in your code there are two objects, and you change object (the pointer) to point to the second object. The first object still exists but nobody knows where it is, this is known as a memory leak.
The thing on left side of = is a pointer i.e to be simple it can contain adrress of some memory location/object instance
When you do new MyClass() -> each execution of this statement will produce a new instance/object/memory of MyClass
So when you do this first time,
MyClass *object1 = new MyClass();
// here object1 now holds the address of object
created by executing 'new MyClass()' suppose that address is 1
Now create a object again,
object1 = new MyClass();
//here object1 now holds the address of object
created by again executing 'new MyClass()' suppose that address is 2
In the end both objects remain in memory i.e 1 as well 2. So nothing is deleted.
The pointer(left side of =) was first pointing to object with adrress 1. Now, it pointing to object with adress 2.
Take this code for example:
class MyClass
{
public:
~MyClass()
{
cout << "Destructor called\n";
}
};
int main()
{
MyClass Testvar;
// destructer called for this
MyClass *ptrvar;
ptrvar = &Testvar;
// but not for this
}
It brings a lots of confusions to me. The code above prints:
Destructor called
only once. I declared two MyClass instances inside main, one of them is a normal variable of type MyClass, and other is a pointer of same type pointing to the normal variable. There is no need of destructor here (no dynamic allocations) but I defined one in the class for a sake of example. So, because two class instances are defined, the destructor should be called twice. But that doesn't happened when I run this code. If I remove the pointer and define one more normal instance, the program prints:
Destructor called
Destructor called
My observation is that destructors are not implicitly called when a pointer instance goes out of scope. Am I right or just missing something.
I declared two MyClass instances inside main
No you didn't. You declared an instance of MyClass and you created a pointer to that instance. That's all.
The behavior of your code is correct.
My observation is that destructors are not implicitly called when a pointer instance goes out of scope. Am I right or just missing something.
That's right. C++ does not provide a garbage collector. You have to keep track of your pointers by yourself. You can use the smart pointers to do so.
You have created only one object and only for that object the destructor is called.
The pointer do not instantiate another object, it simply points to the previous one
Destructors are called when an object allocated on the stack goes out of scope and when object dynamically created (with operator new) are explicitly destroyed (operator delete)
You only actually instantiated one object of type MyClass. That happened in this line:
MyClass Testvar;
In the following line, you only declared a pointer to an object of type MyClass, but this does not create a new object:
MyClass *ptrvar;
And in this line you assigned the address of your first MyClass to your pointer:
ptrvar = &Testvar;
So the pointer is addressing the very same object, you still have only one instance of MyClass. When the scope closes, TestVar is deleted, and you see the destructor called once.
You could have created a new MyClass object (on the heap) and assigned its address to your pointer like this:
MyClass *ptrvar = new MyClass();
Now you really do have two MyClass objects. However, when the scope closes you'll still see only one object being deleted. This is because new creates an object on the heap rather than on the stack, and such objects are not automatically deleted at the end of the scope in which they are created. You have to do this manually using delete:
delete ptrvar;
When this line executes, you'll see your destructor is called. If you don't do this you've left your object on the heap, and have "leaked" the memory it occupies.
To save having to do all of this manually, you should make use of the in-built smart pointers that C++ provides.
This question already has answers here:
What is The Rule of Three?
(8 answers)
Closed 9 years ago.
While designing a class that dynamically allocates memory I ran into the following problem regarding memory allocation. I was hoping that some of you might be able to point me in the right direction as to how I should design my class in a better way. My class dynamically allocates memory and therefore also deletes it in its destructor.
In order to illustrate the problem, consider the following silly class declaration:
class testClass{
int* data;
public:
testClass(){
data = new int;
*data = 5;
}
~testClass(){
delete data;
}
};
So far so good. Now suppose that I create one of these objects in main
int main(){
testClass myObject;
return 0;
}
Still no issues of course. However, suppose that I now write a function that takes a testClass object as an input and call this from main.
void doNoting(testClass copyOfMyObject){
//do nothing
}
int main(){
testClass myObject;
doNothing(myObject);
return 0;
}
This time around, the function creates a local variable, copyOfMyObject, that's simply a copy of myObject. Then when the end of that function is reached, that local object automatically has its destructor called which deletes the memory pointed to by its data pointer. However, since this is the same memory pointed to by myObject's data pointer, myObject inadvertently has its memory deleted in the process. My question is: what is a better way to design my class?
When you call doNothing(), it is making a copy of your testClass object, because it is being passed by value. Unfortunately, when this copy is destroyed, it calls the destructor, which deletes the same data used by the original instance of testClass.
You want to learn about "copy constructors", and "passing by reference". That is, you should define a copy constructor for your class so that when a copy is made of an instance, it allocates its own memory for its data member. Also, rather than passing by value, you could pass a pointer or a reference to doNothing(), so that no copy is made.
You should create a copy constructor, that is a constructor of the form:
testClass::testClass(const testClass &o)
{
// appropriate initialization here
}
In your case, "appropriate initialization" might mean allocate a new chunk of memory and copy the memory from the old chunk into the new chunk. Or it may mean doing reference counting. Or whatever.
You should also read more about the Rule of Three right here on StackOverflow!
Here's a guideline from an authority: A class with any of {destructor, assignment operator, copy constructor} generally needs all 3
You need a copy constructor that will make a new allocated int for your data, that will then destruct that, but not affect the original.
Alternately, you can make a private copy constructor that's blank, which effectively disables it, forcing your users to pass by reference, or another non-copying way of doing things.
this is a really simple question but I havn't done c++ properly for years and so I'm a little baffled by this. Also, it's not the easiest thing (for me at least) to look up on the internet, not for trying.
Why doesn't this use the new keyword and how does it work?
Basically, what's going on here?
CPlayer newPlayer = CPlayer(position, attacker);
This expression:
CPlayer(position, attacker)
creates a temporary object of type CPlayer using the above constructor, then:
CPlayer newPlayer =...;
The mentioned temporary object gets copied using the copy constructor to newPlayer. A better way is to write the following to avoid temporaries:
CPlayer newPlayer(position, attacker);
The above constructs a CPlayer object on the stack, hence it doesn't need new. You only need to use new if you are trying to allocate a CPlayer object on the heap. If you're using heap allocation, the code would look like this:
CPlayer *newPlayer = new CPlayer(position, attacker);
Notice that in this case we're using a pointer to a CPlayer object that will need to be cleaned up by a matching call to delete. An object allocated on the stack will be destroyed automatically when it goes out of scope.
Actually it would have been easier and more obvious to write:
CPlayer newPlayer(position, attacker);
A lot of compilers will optimise the version you posted to the above anyway and it's clearer to read.
CPlayer newPlayer = CPlayer(position, attacker);
This line creates a new local object of type CPlayer. Despite its function-like appearance, this simply calls CPlayer's constructor. No temporaries or copying are involved. The object named newPlayer lives as long as the scope it's enclosed in. You don't use the new keyword here because C++ isn't Java.
CPlayer* newPlayer = new CPlayer(position, attacker);
This line constructs a CPlayer object on the heap and defines a pointer named newPlayer to point at it. The object lives until someone deletes it.
newPlayer is no dynamically allocated variable but an auto, stack-allocated variable:
CPlayer* newPlayer = new CPlayer(pos, attacker);
is different from
CPlayer newPlayer = CPlayer(pos, attacker);
newPlayer is allocated on the stack via the normal CPlayer(position, attacker) constructor invocation, though somewhat verbose than the usual
CPlayer newPlayer(pos, attacker);
It's basically the same as saying:
int i = int(3);
I declared a private variable
vector<SomeClass> theVector;
someplace inside my SomeClass class.
Why can't I say: delete theVector inside my SomeClass destructor?
The compiler error says:
type `class Vector<SomeClass>' argument given to `delete', expected pointer
What expected pointer?
If new and delete go hand in hand.
To delete something you need to create it via new (which gives you a pointer). You can then delete the pointer. The way you are declaring the vector it is being created on the stack (not the heap) and will be deallocated when it goes out of scope.
int main()
{
vector<SomeClass> theVector;
vector<SomeClass>* ptrVctor = new vector<SomeClass>();
delete ptrVctor; // ptrVctor must be deleted manually
// theVector destroyed automatically here
}
In C++ (unlike Java), you can create objects either on the stack or the heap. An example of creating it on the stack is, as you have done:
vector<SomeClass> theVector;
This object goes out of scope when the stack frame disappears (normally when you return from the function that created the object.
Creating objects on the heap allows them to outlive the function that created them and you do that by performing:
vector<SomeClass> *theVectorPtr = new vector<SomeClass>();
You can then pass the theVectorPtr pointer back to the caller of the function (or store it globally, whatever you want).
In order to get rid of the object on the heap, you explicitly delete it:
delete theVectorPtr;
somewhere in your code.
Deleting an object on the heap ends the scope of that object, the same way returning from a function ends the scope of variables created on the stack.
If an object (rather than a value) is defined as a class member variable, then its storage is always tied to the object instance of that class.
Therefore, if the containing object is allocated on the stack, then that object and the field will die when the stack unrolls.
If the containing object is allocated on the heap, then the field object will die when the entire containing object dies with delete.
You will only be applying delete to a field if that is a pointer, since all that is stored with the containing object is the address of some other memory area, and you are deleting the materials in that area.
The memory for theVector is part of the memory allocated for the SomeClass object, so you can't delete it without deleting the entire SomeClass object. The memory for theVector will get automatically freed when the SomeClass object is destructed.
This is because theVector is not a pointer, which is what delete' expects. "Expected pointer" means the operand ofdelete' must be a pointer.
Compare this to
int theInt;
delete theInt;
It surely will generate an error similar to what you got.
To destroy all of the objects held in the vector, you would do the following:
theVector.resize(0);
This will happen automatically when the vector goes out of scope.
c++ gives you flexibility to create object in stack and heap.
When the object is created in heap through new operator as shown below it returns the pointer to the object in heap.
ClassA * pobj_class = new ClassA();
For object created in stack the constructor returns the object rather than pointer as shown below.
ClassA obj_class();
and stack object automatically destroyed when variable(obj_class) goes out of scope,but object created on heap lives for ever.So to destroy heap object c++ gives you delete operator that takes pointer as argument and destroys the object the pointer is pointing to.