can I declare new variables, like one of a different class,
in a c'tor?
Assume I have a class named List and a Node (nested in the List class), then I want to do:
List::List(int num)
{
Node Nod(num); //creating a new Node which is holding num
List_Head=&Nod; //List_Head is a Node pointer variable of List class
}
Once I do that, I get the following Runtime error:
Debug Assertion Failed!
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
Any help?
The scope and lifetime of Nod you create is limited to the constructor List::List() Since it is a local/automatic object.
Once the constructor returns Nod does not exist and anything pointing to it(List_Head) is a dangling pointer, deferencing it would cause Undefined Behavior and most likely a crash.
You should be creating the Node on dynamic memory(heap) by calling new if you want to refer it beyond the constructor body.
List_Head = new Node(num);
ideally, You should use some sort of an smart pointer instead of raw pointer for List_Head so that you don't have to the manual memory management. If you can't you have to call:
delete List_Head;
after you are done with your usage so as to avoid a memory leak.
You can't do it like that. Nod goes out of scope at the end of the constructor (the last }), which means its memory gets invalidated, which means that List_Head is pointing to invalid memory.
If you want to keep the memory around, you have to use new, like
List_Head = new Node(num);
Just be sure to delete what you new! But you have to be careful with this! Memory can leak if you don't delete it, or it can be double deleted if you don't handle it right. Specifically, you need to be sure to also implement the destructor, copy constructor, and assignment operator to properly handle the memory you allocate.
Alternatively, you can use smart pointers (such as std::shared_ptr if you're using C++11) to handle the deletions for you so you don't leak memory or double delete memory. You may have to still define your copy constructor and assignment operator though, depending on how you want your class to act (because without custom versions of these, you'll get a shallow copy of the object instead of a deep copy, which may not be what you want).
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 went through this post and had a doubt. Is it a good practice to null an element of an object in its destructor?
The destructor will be called when the object goes out of scope but will its elements need to be set to NULL in the destructor to ensure dangling pointers are not left.
After an object is destroyed, it ceases to exist. There is no point in setting its members to particular values when those values will immediately cease to exist.
The pattern of setting pointers to NULL when deleteing the objects they point to is actively harmful and has caused errors in the past. Unless there's a specific reason the pointer needs to be set to NULL (for example, it is likely to be tested against NULL later) it should not be set to NULL.
Consider:
Foo* foo getFoo();
if (foo!=NULL)
{
do_stuff();
delete foo;
}
// lots more code
return (foo == NULL);
Now, imagine if someone adds foo = NULL; after the delete foo; in this code, thinking that you're supposed to do that. Now the code will give the wrong return value.
Next, consider this:
Foo* foo getFoo();
Foo* bar = null;
if (foo != NULL)
{
bar = foo;
do_stuff(bar);
delete bar;
bar = NULL;
}
// lots more code
delete foo;
We always set pointers to NULL after we delete them, so this delete foo; must be safe, right? Clearly it's not. So setting pointers to NULL after you delete them is neither necessary nor sufficient.
Don't do it.
It's not necessary to set member elements to NULL in the destructor, as delete has been called on the owner object in order for that destructor to be called. It is the responsibility of the code that deletes an object to no longer try to access the contents of that object.
You are also using extra cycles clearing out that memory.
The point of doing this is to provide deterministic behavior in event of a programming error.
If the deleted pointer is used, then the program will always fail on dereferencing a nullptr. (Not allowing the program to continue.)
If the deleted pointer set to nullptr and is then deleted again, then the second attempt is a noop (by design).
This is the normal pattern for pointers that are NOT deleted in a destructor. (Smart pointers are your friend, to avoid this situation, entirely.)
The purpose of nulling a deleted member pointer in a destructor is less obvious; when there is a suspicion that other code may have a reference to that member. This should generally be avoided (to rely on this), because it has limited utility once the memory for the destructed class is reclaimed. Although implementation dependent, in many environments the memory can live long enough to cause the program to fail when the deleted memory is re-used, so that the programmer can find the issue and fix it.
So it's been a while since I've done any c++ coding and I was just wondering which variables in a basic linked list should be deleted in the destructor and unfortunately I can't consult my c++ handbook at the moment regarding the matter. The linked list class looks as follows:
#include <string>
#include <vector>
class Node
{
Node *next;
string sName;
vector<char> cvStuff;
Node(string _s, int _i)
{
next = nullptr;
sName = _s;
for (int i = 0; i < _i; i++)
{
cvStuff.insert(cvStuff.end(), '_');
}
}
~Node()
{
//since sName is assigned during runtime do I delete?
//same for cvStuff?
}
};
I'm also curious, if in the destructor I call
delete next;
will that go to the next node of the linked list and delete that node and thus kind of recursively delete the entire list from that point? Also, if that is the case and I choose for some reason to implement that, would I have to check if next is nullptr before deleting it or would it not make a difference?
Thank you.
Ideally, nothing: use smart pointers: std::unique_ptr<>, std::smart_ptr<>, boost::scoped_ptr<>, etc..
Otherwise, you delete what's an owning native pointer. Is next owning?
Do you plan to delete something in the middle of the list? If yes, you can't delete in the destructor.
Do you plan to share tails? If yes, you need reference-counted smart pointers.
It's okay to delete nullptr (does nothing). In the example, you shouldn't delete sName and cvStuff as those are scoped, thus destroyed automatically.
Also, if this is going to be a list that can grow large, you might want to destroy & deallocate *next manually. This is because you don't want to run out of stack space by recursion.
Furthermore, I suggest separating this to List, meaning the data structure and ListNode, meaning an element. Your questions actually show this ambiguity, that you don't know whether you're deleting the ListNode or the List in the destructor. Separating them solves this.
An object with automatic lifetime has it's destructor called when it goes out of scope:
{ // scope
std::string s;
} // end scope -> s.~string()
A dynamic object (allocated with new) does not have it's destructor called unless delete is called on it.
For a member variable, the scope is the lifetime of the object.
struct S {
std::string str_;
char* p_;
};
int main() { // scope
{ // scope
S s;
} // end scope -> s.~S() -> str_.~string()
}
Note in the above that nothing special happens to p_: it's a pointer which is a simple scalar type, so the code does nothing automatic to it.
So in your list class the only thing you have to worry about is your next member: you need to decide whether it is an "owning" pointer or not. If it is an "owning" pointer then you must call delete on the object in your destructor.
Alternatively, you can leverage 'RAII' (resource aquisition is initialization) and use an object to wrap the pointer and provide a destructor that will invoke delete for you:
{ // scope
std::unique_ptr<Node> ptr = std::make_unique<Node>(args);
} // end scope -> ptr.~unique_ptr() -> delete -> ~Node()
unique_ptr is a purely owning pointer, the other alternative might be shared_ptr which uses ref-counting so that the underlying object is only deleted when you don't have any remaining shared_ptrs to the object.
You would consider your next pointer to be a non-owning pointer if, say, you have kept the actual addresses of the Nodes somewhere else:
std::vector<Node> nodes;
populate(nodes);
list.insert(&nodes[0]);
list.insert(&nodes[1]);
// ...
in the above case the vector owns the nodes and you definitely should not be calling delete in the Node destructor, because the Nodes aren't yours to delete.
list.insert(new Node(0));
list.insert(new Node(1));
here, the list/Nodes are the only things that have pointers to the nodes, so in this use case we need Node::~Node to call delete or we have a leak.
Basically you should just
delete next
and that's all you should do:
The string and vector objects have their own destructors, and since this object is being destructed, theirs will be called.
Deleting a null pointer is not a problem, so you don't even have to check for that.
If next is not a null pointer, it will keep on calling the destructors of the next nodes, on and on, as needed.
Just delete it and that's all, then.
Your class destructor will be called (it is empty), then the member objects destructors are called.
If member is not an object, no destructor is called.
In your example:
- List *next: pointer on List: no destructor called
- string sName: string object: destructor called
- vector<char> cvStuff: vector object: destructor called
Good news: you have nothing to do. Destructor declaration is not even useful here.
If you delete next in your destructor, then deleting an item will delete all other items of your list: not very useful.
(and your List object should rather be called Node). The List is the chained result of all your nodes, held by the first node you created.
This question already has answers here:
Does std::list::remove method call destructor of each removed element?
(6 answers)
Closed 9 years ago.
I have a class that contains pointers, the class inherits nothing
class MyClass
{
public:
MyClass();
~MyClass();
private:
//i have pointers here
};
MyClass::~MyClass()
{
print("destroyed..");
}
Now i have to use this class as a pointer in vector like this:
vector<MyClass*> classes;
Push some classes in here but when i remove an element:
classes.remove(index);
The destructor doesn't get called,and i think that I have a memory leak.
So how do i make it call the destructor
A vector of pointers does nothing to delete the pointers when they get removed or cleared from it. The vector cannot know if the pointers are dynamically allocated or not. It is not it's job to call delete.
It is up to you to call delete on the pointers, if and when it is necessary. There are not enough details in your question to determine whether it is necessary at all (you haven't shown how the objects pointed to are allocated). But since you claim there is a memory leak, this could indicate that they are dynamically allocated. The immediate solution is to call delete:
delete *it;
classes.erase(it); // vector has no remove member function
A safer solution is to store unique ownership smart pointers, such as std::unique_ptr<MyClass>. The standard library also provides smart pointers for shared and weak ownership. See Smart Pointers.
All the above is assuming that you do actually need to store a pointer. In general, it is safer and clearer to store values:
std::vector<MyClass> classes; // but don't call it "classes". A vector stores objects.
That's one of the reasons why you should avoid using std::vector<MyClass*> at first place. There's an ugly memory management connected with it and it won't stay as easy as classes.remove(index);
Basically, for every new a delete must be called and for every new[] a delete[] must be called, no matter whether you use this pointer as a local variable or you put it into the vector:
vector<MyClass*> vec;
vec.push_back(new MyClass()); // <-- object has been created
...
delete classes[index]; // <-- object shall be destructed
// the delete call will automatically invoke the destructor if needed
...
// now you can remove the dangling pointer from the vector
Just note that once the object has been destructed, any (old) reference to this object is invalid and trying to access this object using such reference (dangling pointer) will yield undefined behavior.
Firstly, std::vector has no remove, you probably mean erase.
Secondly, you need to manually call delete on whatever you're removing:
vector<MyClass*> classes;
auto iter = <iterator to index to remove>;
delete *iter;;
classes.erase(iter);
Or, to avoid all this pain, use a std::unique_ptr<MyClass>.
It is unclear who is responsible for managing the lifetime of the objects pointed by the pointers inside classes. Have you pushed newed pointers into it, or have you pushed the addresses of automatic storage objects?
If you have done the former, then you must manually delete the pointer before removing it. Else, if you have done the latter, then you could just leave it as is, just leaving the pointed-to objects destroy themselves as they leave their respective scopes. If you have mixed newed and non-newed pointers, whose possibility isn't that remote as you would think, then you're definitely damned, undefined behavior making demons fly out of your nose.
These kinds of situations involving pointers are very ambiguous, and it is generally recommended not to use pointers at all, and make the std::vector store plain objects, which makes your object lifetime management much simpler and the making the declaration just speak for itself.
vector<MyClass> classes; // Do this instead
You have to manually delete your pointers before your application exit or after your class object is removed from vector.
// Delete all
vector<MyClass*>::iterator it = classes.begin();
while (it != classes.end()) {
delete *it;
it = classes.erase(it);
}
Tip: Never add stack constructed pointers like following:
MyClass m;
classes.push_back(&m);
Edit: As suggested by other member the better solution is:
MyClass m(/* ... */);
vector<MyClass> classes;
classes.push_back(m);
However please note, you have to properly implement the copy constructor especially if your class has pointer data members that were created with new.
Make a temp pointer to hole MyClass* pointer before you remove it from your vector.
vector<MyClass*> classes;
//push some classes in here but
//when i remove an element
MyClass* temp = classes[index];
classes.remove(index);
// call delete temp; if you want to call the destructor thus avoid memory leak.
delete temp;
To avoid memory leak, remember never to loose control of heap object, always keep a a pointer or reference to it before object release.
It seems that you want your vector to be manager of your items.
Take a look at boost::ptr_vector class
its basically a wrapper around std::vector class.
You declare that this vector is the "holder" of these pointers, and if you remove them from this containers you want them to be deleted.
#include <boost/ptr_container/ptr_vector.hpp>
...
boost::ptr_vector<MyClass> myClassContainer;
myClassContainer.push_back(new MyClass());
myClassContainer.clear(); // will call delete on every stored object!
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!