As I understand if the member function has been called using pointer to an object which is allocated dynamically, the object would get delete. But if the member function has been called using the object, which is allocated statically, then what will happen ?
class sample
{
int i;
public:
void func()
{
delete this;
}
};
void main()
{
sample *s = new sample;
s->fun();
sample s1;
s1.fun();
}
Deleting a pointer inside a member function is OK, as long as you know how that pointer has been allocated. There is no portable way of knowing that from just a pointer alone.
If a function is passed a pointer that has not been allocated dynamically, and the function calls delete on that pointer, it is undefined behavior. Moreover, even pointers to dynamic objects allocated as arrays cannot be freed with the regular delete operator: you must use delete[] on them. A simple rule is that when you do not know the origin of a pointer, you do not call delete on it.
You can only use delete if the object was allocated using new. Simple as that. Therefore the first example you gave is legal, the second is not. The second case is likely to crash, or worse, cause heap corruption and crash at a seemingly random memory allocation somewhere far removed from the problem.
If you call delete this inside any member function of object which is statically allocated , then calling delete this will crash at runtime . Because when this object will go out of scope , compiler will automatically call destructor , which will try to delete object which no longer exists.
Related
I've got the following class:
now I've been thinking of implementing my constructor this way:
basically dereferncing the object returned by the new operation.
now ... this feels wrong and I should probably should have be working with pointers, but I'd like to challange myself to maybe get this to work and learn something new.
So my problem will be deleting this object... my destructor for Dense does not work as I have it like this:
but obviously I'm getting this error:
free(): invalid pointer
so how can I go about freeing the allocated memory with the way I have this implemented?
Thanks.
There is no need to do it this complicated. You can call the constructors directly from the initializer list. There is absolutely no need for new here. Also you don't need to delete those objects. Their destructors will be called automatically if Dense gets destroyed.
Dense::Dense(): weights(), //Calls constructor Matrix()
bias(), //Calls constructor Matrix()
act(ActivationType::Relu), //Calls constructor Activation(ActivationType::Relu)
input() //Calls constructor Matrix()
{}
Also, what you are trying to do with pointers wont work. For example &bias will be the address of the member variable bias and has nothing to do with the pointer returned by new Matrix().
so how can I go about freeing the allocated memory with the way I have this implemented?
You simply can't and you have created a memory leak.
Explanation:
When you write:
int a = *(new int(5)); // Really bad
You basically:
allocate an int on the heap
dereference the r-value
assign it (copy) to a variable on the stack
At no moment you did care to keep the returned pointer of the new statement. a is another int that is a copy of what you've allocated on the heap.
You can't delete a because it is created on the stack. As a is another object, the address of a is not the same as the address of the int you've allocated on the heap with new.
So deleting &a is obviously forbidden Undefined Behaviour and cannot in any way delete the int that you've created with new. And as you did not stored the returned pointer of the new statement, you have no way to retrieve it: This is a memory leak.
If you got a reference instead of a copy, you would be able to delete it:
int & a = *(new int(5));
delete &a; // fine
But it is an over-complicated, less efficient and pointless way of simply doing:
int a = 5; // destroyed at scope's end
I would like to have a class contain a std::unique_ptr initialized by the constructor then used elsewhere in the class.
So I've got a class that contains a std::unique_ptr like this:
class ObjectA
{
public:
ObjectA();
~ObjectA();
void SomeFunction();
private:
std::unique_ptr<ObjectB> myPointer;
}
Then in the class's source file myPointer is setup in the constructor and used in SomeFunction().
ObjectA::ObjectA()
{
ObjectC objectC;
myPointer = std::move(std::unique_ptr<ObjectB>(objectC.getPointer())); //setup pointer
}
ObjectA::~ObjectA() {}
void ObjectA::SomeFunction()
{
//use myPointer here
}
The problem though, is that I can't use myPointer in SomeFunction(), and here's why.
Obviously myPointer must be allocated on the heap to assure it doesn't get destroyed when the constructor is done executing. Assume that ObjectC and consequentially it's functions are from an external library. When I call ObjectC::getPointer() the pointer that's return is probably allocated on the stack apposed to the heap. Now I assume this is the case because right after the constructor has finished executing I get an error.
Basically I'm relying on a function to give me a pointer with wich I can then use elsewhere. However, the function allocates the object on the stack instead of the heap.
Is there some special way to solve this problem, maybe with a double pointer? Or will I just have to call ObjectC::getPointer() every time I want to use the pointer inside each execution block? If I had lots of functions inside ObjectA which rely on myPointer then calling ObjectC::getPointer() per function would be redundant, but I don't know if there is a better way to fix this, and I feel like a function (ObjectC::getPointer()) shouldn't force me into that redundancy.
When you call ObjectC::getPointer(), you don't just get "a" pointer. The function must specify what operations are valid on the pointer, and in particular how it should be disposed.
Usually, that would be delete, but it could also be e.g. fclose. You'll have to read the documentation. If the lifetime of the returned pointer matches that lifetime of objectC, then the lifetime of objectC should match myPointer. So it probably should be a member, and that in turn means that myPointer might be redundant. You could just substitute private: ObjectB& getB() { return *myObjectC.GetPointer(); }
Following class will be initiated with a member variable newTodayTaskString (string).
When destructing the object I like to delete the string but when compiling the project I get an error message pointing to the destructor delete line saying:
delete: std::string cannot be converted to void
Class:
class TodayTask {
private:
string newTodayTaskString;
public:
TodayTask (string t) : newTodayTaskString (t){}
// Destr.
~TodayTask () {
delete newTodayTaskString;
}
string getTodayTaskString () const {
return newTodayTaskString;
}
};
delete must be given a pointer, and can only be used to destroy objects created with new.
In this case, the object is a class member, and so will be destroyed automatically. You don't need to do anything with it in the destructor.
In c++, memory can be allocated either automaticaly or manualy.
If you define a simple variable, the memory for it is allocated automaticaly, in the Stack. The memory is then automatically freed. For example:
void foo()
{
std::string s;//memory is allocated here
}//the variable only lives inside the function, so at this point the memory is freed
The second way is to allocate the memory manualy, with the operator new, like this:
void foo()
{
int * i = new int();//we allocate the memory for our variable here.
}
Here, the memory is alocated in the heap, and it will not be freed automaticaly in the end of the funciton, or anywhere else until your programm ends.
In this case, you need to call operator delete, but you must call it only once for each variable:
void foo()
{
int * i = new int();
<...some code...>
delete i;//we free the memory at this point.
}
Note that if you will try to delete the same variable twice, you might get a segmentation fault.
In your case you are trying to manualy delete a variable for which you have not manually allocated the memory, which leads to the error. In your case you don't need to bother with the destructor, everything will be done automaticaly.
delete is only needed when the object is created using new. In this case, your object is automatically created before the constructor since it is a member variable. Thus, it is automatically destroyed after the destructor is called.
You should use delete only when you created it using new
You don't 'delete' newTodayTaskString, since it hasn't been allocated with 'new'. It's a member variable -- it will be automatically constructed and destructed, there's nothing you have to do.
You don't need to delete newTodayTaskString as it is not you who allocates its memory
You really don't have to delete the string. It's not dynamically allocated.
Just remember this:
use delete when you new something.
use delete[] when you new an array of something.
I have a class pointer declaration:
MyClass* a;
In destruction method I have:
if (a)
{
delete a;
a= NULL;
}
I got a problem when delete the pointer a:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
What is the cause of the problem and how can I get rid of it?
With your current declaration:
MyClass* a;
a gets a random value. If you never give it a valid value later, such as:
a = new MyClass();
It will point to an unknown place in memory, quite probably not a memory area reserved for your program, and hence the error when you try to delete it.
The easiest way to avoid this problem is to give a a value when you declare it:
MyClass* a = new MyClass();
or, if you cannot give it a value when you declare it (maybe you don't know it yet), assign it to null:
MyClass* a = 0;
By the way, you can remove the test (if (a)) from your code. delete is a no-op on a null pointer.
Use smart pointer to free memory. delete in application code is always wrong.
unless you have initialized the pointer to something after this:
MyClass* a;
the pointer a will hold some random value. So your test
if (a) { }
will pass, and you attempt to delete some random memory location.
You can avoid this by initializing the pointer:
MyClass* a = 0;
Other options are that the object pointed to has been deleted elsewhere and the pointer not set to 0, or that it points to an object that is allocated on the stack.
As has been pointed out elsewhere, you could avoid all this trouble by using a smart pointer as opposed to a bare pointer in the first place. I would suggest having a look at std::unique_ptr.
How did you allocate the memory that a points to? If you used new[] (in order to create an array of MyClass), you must deallocate it with delete[] a;. If you allocated it with malloc() (which is probably a bad idea when working with classes), you must deallocate it with free().
If you allocated the memory with new, you have probably made a memory management error somewhere else - for instance, you might already have deallocated a, or you have written outside the bounds of some array. Try using Valgrind to debug memory problems.
You should use
MyClass* a = NULL;
in your declaration. If you never instantiate a, the pointer is pointing to an undefined region of memory. When the containing class destructor executes, it tries to delete that random location.
When you do MyClass* a; you declare a pointer without allocating any memory. You don't initialize it, and a is not necessarily NULL. So when you try to delete it, your test if (a) succeeds, but deallocation fails.
You should do MyClass* a = NULL; or MyClass* a(nullptr); if you can use C++11.
(I assume here you don't use new anywhere in this case, since you tell us that you only declare a pointer.)
Basic Question: when does a program call a class' destructor method in C++? I have been told that it is called whenever an object goes out of scope or is subjected to a delete
More specific questions:
1) If the object is created via a pointer and that pointer is later deleted or given a new address to point to, does the object that it was pointing to call its destructor (assuming nothing else is pointing to it)?
2) Following up on question 1, what defines when an object goes out of scope (not regarding to when an object leaves a given {block}). So, in other words, when is a destructor called on an object in a linked list?
3) Would you ever want to call a destructor manually?
1) If the object is created via a pointer and that pointer is later deleted or given a new address to point to, does the object that it was pointing to call its destructor (assuming nothing else is pointing to it)?
It depends on the type of pointers. For example, smart pointers often delete their objects when they are deleted. Ordinary pointers do not. The same is true when a pointer is made to point to a different object. Some smart pointers will destroy the old object, or will destroy it if it has no more references. Ordinary pointers have no such smarts. They just hold an address and allow you to perform operations on the objects they point to by specifically doing so.
2) Following up on question 1, what defines when an object goes out of scope (not regarding to when an object leaves a given {block}). So, in other words, when is a destructor called on an object in a linked list?
That's up to the implementation of the linked list. Typical collections destroy all their contained objects when they are destroyed.
So, a linked list of pointers would typically destroy the pointers but not the objects they point to. (Which may be correct. They may be references by other pointers.) A linked list specifically designed to contain pointers, however, might delete the objects on its own destruction.
A linked list of smart pointers could automatically delete the objects when the pointers are deleted, or do so if they had no more references. It's all up to you to pick the pieces that do what you want.
3) Would you ever want to call a destructor manually?
Sure. One example would be if you want to replace an object with another object of the same type but don't want to free memory just to allocate it again. You can destroy the old object in place and construct a new one in place. (However, generally this is a bad idea.)
// pointer is destroyed because it goes out of scope,
// but not the object it pointed to. memory leak
if (1) {
Foo *myfoo = new Foo("foo");
}
// pointer is destroyed because it goes out of scope,
// object it points to is deleted. no memory leak
if(1) {
Foo *myfoo = new Foo("foo");
delete myfoo;
}
// no memory leak, object goes out of scope
if(1) {
Foo myfoo("foo");
}
Others have already addressed the other issues, so I'll just look at one point: do you ever want to manually delete an object.
The answer is yes. #DavidSchwartz gave one example, but it's a fairly unusual one. I'll give an example that's under the hood of what a lot of C++ programmers use all the time: std::vector (and std::deque, though it's not used quite as much).
As most people know, std::vector will allocate a larger block of memory when/if you add more items than its current allocation can hold. When it does this, however, it has a block of memory that's capable of holding more objects than are currently in the vector.
To manage that, what vector does under the covers is allocate raw memory via the Allocator object (which, unless you specify otherwise, means it uses ::operator new). Then, when you use (for example) push_back to add an item to the vector, internally the vector uses a placement new to create an item in the (previously) unused part of its memory space.
Now, what happens when/if you erase an item from the vector? It can't just use delete -- that would release its entire block of memory; it needs to destroy one object in that memory without destroying any others, or releasing any of the block of memory it controls (for example, if you erase 5 items from a vector, then immediately push_back 5 more items, it's guaranteed that the vector will not reallocate memory when you do so.
To do that, the vector directly destroys the objects in the memory by explicitly calling the destructor, not by using delete.
If, perchance, somebody else were to write a container using contiguous storage roughly like a vector does (or some variant of that, like std::deque really does), you'd almost certainly want to use the same technique.
Just for example, let's consider how you might write code for a circular ring-buffer.
#ifndef CBUFFER_H_INC
#define CBUFFER_H_INC
template <class T>
class circular_buffer {
T *data;
unsigned read_pos;
unsigned write_pos;
unsigned in_use;
const unsigned capacity;
public:
circular_buffer(unsigned size) :
data((T *)operator new(size * sizeof(T))),
read_pos(0),
write_pos(0),
in_use(0),
capacity(size)
{}
void push(T const &t) {
// ensure there's room in buffer:
if (in_use == capacity)
pop();
// construct copy of object in-place into buffer
new(&data[write_pos++]) T(t);
// keep pointer in bounds.
write_pos %= capacity;
++in_use;
}
// return oldest object in queue:
T front() {
return data[read_pos];
}
// remove oldest object from queue:
void pop() {
// destroy the object:
data[read_pos++].~T();
// keep pointer in bounds.
read_pos %= capacity;
--in_use;
}
~circular_buffer() {
// first destroy any content
while (in_use != 0)
pop();
// then release the buffer.
operator delete(data);
}
};
#endif
Unlike the standard containers, this uses operator new and operator delete directly. For real use, you probably do want to use an allocator class, but for the moment it would do more to distract than contribute (IMO, anyway).
When you create an object with new, you are responsible for calling delete. When you create an object with make_shared, the resulting shared_ptr is responsible for keeping count and calling delete when the use count goes to zero.
Going out of scope does mean leaving a block. This is when the destructor is called, assuming that the object was not allocated with new (i.e. it is a stack object).
About the only time when you need to call a destructor explicitly is when you allocate the object with a placement new.
1) Objects are not created 'via pointers'. There is a pointer that is assigned to any object you 'new'. Assuming this is what you mean, if you call 'delete' on the pointer, it will actually delete (and call the destructor on) the object the pointer dereferences. If you assign the pointer to another object there will be a memory leak; nothing in C++ will collect your garbage for you.
2) These are two separate questions. A variable goes out of scope when the stack frame it's declared in is popped off the stack. Usually this is when you leave a block. Objects in a heap never go out of scope, though their pointers on the stack may. Nothing in particular guarantees that a destructor of an object in a linked list will be called.
3) Not really. There may be Deep Magic that would suggest otherwise, but typically you want to match up your 'new' keywords with your 'delete' keywords, and put everything in your destructor necessary to make sure it properly cleans itself up. If you don't do this, be sure to comment the destructor with specific instructions to anyone using the class on how they should clean up that object's resources manually.
Pointers -- Regular pointers don't support RAII. Without an explicit delete, there will be garbage. Fortunately C++ has auto pointers that handle this for you!
Scope -- Think of when a variable becomes invisible to your program. Usually this is at the end of {block}, as you point out.
Manual destruction -- Never attempt this. Just let scope and RAII do the magic for you.
To give a detailed answer to question 3: yes, there are (rare) occasions when you might call the destructor explicitly, in particular as the counterpart to a placement new, as dasblinkenlight observes.
To give a concrete example of this:
#include <iostream>
#include <new>
struct Foo
{
Foo(int i_) : i(i_) {}
int i;
};
int main()
{
// Allocate a chunk of memory large enough to hold 5 Foo objects.
int n = 5;
char *chunk = static_cast<char*>(::operator new(sizeof(Foo) * n));
// Use placement new to construct Foo instances at the right places in the chunk.
for(int i=0; i<n; ++i)
{
new (chunk + i*sizeof(Foo)) Foo(i);
}
// Output the contents of each Foo instance and use an explicit destructor call to destroy it.
for(int i=0; i<n; ++i)
{
Foo *foo = reinterpret_cast<Foo*>(chunk + i*sizeof(Foo));
std::cout << foo->i << '\n';
foo->~Foo();
}
// Deallocate the original chunk of memory.
::operator delete(chunk);
return 0;
}
The purpose of this kind of thing is to decouple memory allocation from object construction.
Remember that Constructor of an object is called immediately after the memory is allocated for that object and whereas the destructor is called just before deallocating the memory of that object.
Whenever you use "new", that is, attach an address to a pointer, or to say, you claim space on the heap, you need to "delete" it.
1.yes, when you delete something, the destructor is called.
2.When the destructor of the linked list is called, it's objects' destructor is called. But if they are pointers, you need to delete them manually.
3.when the space is claimed by "new".
Yes, a destructor (a.k.a. dtor) is called when an object goes out of scope if it is on the stack or when you call delete on a pointer to an object.
If the pointer is deleted via delete then the dtor will be called. If you reassign the pointer without calling delete first, you will get a memory leak because the object still exists in memory somewhere. In the latter instance, the dtor is not called.
A good linked list implementation will call the dtor of all objects in the list when the list is being destroyed (because you either called some method to destory it or it went out of scope itself). This is implementation dependent.
I doubt it, but I wouldn't be surprised if there is some odd circumstance out there.
If the object is created not via a pointer(for example,A a1 = A();),the destructor is called when the object is destructed, always when the function where the object lies is finished.for example:
void func()
{
...
A a1 = A();
...
}//finish
the destructor is called when code is execused to line "finish".
If the object is created via a pointer(for example,A * a2 = new A();),the destructor is called when the pointer is deleted(delete a2;).If the point is not deleted by user explictly or given a new address before deleting it, the memory leak is occured. That is a bug.
In a linked list, if we use std::list<>, we needn't care about the desctructor or memory leak because std::list<> has finished all of these for us. In a linked list written by ourselves, we should write the desctructor and delete the pointer explictly.Otherwise, it will cause memory leak.
We rarely call a destructor manually. It is a function providing for the system.
Sorry for my poor English!