A few questions:
I was looking at the following code for a linked list on www.cprogramming.com:
struct node {
int x;
node *next;
};
int main()
{
node *root; // This will be the unchanging first node
root = new node; // Now root points to a node struct
root->next = 0; // The node root points to has its next pointer
// set equal to a null pointer
root->x = 5; // By using the -> operator, you can modify the node
// a pointer (root in this case) points to.
}
Would this code cause a [small] memory leak because he never deletes root at the end?
Also, would this be any different if 'node' was a class instead of a struct?
Finally, for this code:
#include <iostream>
using namespace std;
class A
{
public:
A(){}
void sing()
{ cout << "TEST\n";}
};
int main()
{
A *a = new A();
a->sing();
return 0;
}
Would I have to delete A before exiting main?
In what instances would I use A *a = new A() versus using A a = A() ?
1.1 Yes, although on any modern operating system when the process ends all its memory is reclaimed by the operating system. Memory leaks are a big problem for long lived processes, where memory continues to be leaked and the process continues to ask for more memory for no apparent reason.
1.2 I suppose you meant a class, not an object (an object is an instantiation of a class or of a struct)... still, there would be no difference, class and struct differ only in their default access specifier (public for structs, private for classes).
2.1 Yes (with the same caveat as in 1.1).
2.2 Usually when (a) A is too big to be placed on the stack, (b) when the object lifetime imposed by local variables (=automatic destruction at the end of the scope) is not appropriate, (c) when the number of objects to be create is not known at compile-time.
Examples:
a. A contains in its definition a really big matrix, that would take away a lot of stack space; or, A is not that big, but the current call is recursive, so putting it on the stack would be likely to lead to a stack overflow.
b. A is an object to be returned from this function (and a copy is not acceptable); or, A is to be created in this function and to be deleted in the future by some other function, but not at the end of the current scope.
c. A is a node of a linked list to be populated with data provided by the user; you create and append the nodes in a loop until the user provided data ends.
For the first part:
It might be sloppy (and tools like Valgrind will warn about it), but all memory is freed by the OS when main returns. A memory leak is more of a concern if it persists as the program continues to run.
There is no distinction in C++ between "classes" and "structs". A class simply has its initial access modified as private rather than public.
And for the later part:
Same as 1.
This is a fairly complicated question. Broadly, you'll want to use heap memory allocation (which is what new does) in cases where the object needs to outlive the current scope (e.g. to be returned by the function in which it is constructed) or its size is determined dynamically or can be very large, among other reasons.
Would this code cause a [small] memory leak because he never deletes root at the end?
Yes, however the program is terminated and the memory should be reclaimed by the OS. So any memory leak checks would flag this.
Also, would this be any different if 'node' was an object instead of a struct?
No. Structs and Classes are nearly identical, except that the default protection for a struct is public
Would I have to delete A before exiting main?
Yes. To avoid a memory leak.
In what instances would I use A *a = new A() versus using A a = A() ?
Using operator new will allocate the memory on the heap. It's preferred to allocated on the stack, unless you need your object to live past the life of the stack-frame, in which case you can either return by copy, or allocate it on the heap, where it will remain until it is deleted.
First Part
1) Yes, there is a memory leak.
2) There is no functional difference between a class and a struct.
Second Part
1) Yes, you should delete any object that you allocate on the heap.
2) In any case where you can avoid pointers (and allocating heap memory, for that matter), you should. It takes less time and uses less resources to use the stack.
In this case the lifetime of the object is so short that it makes no sense to use the heap.
Related
So when we actually create the node object, why does it have to be a pointer. Why cant be just make it a regular Node object, use . for the data and then use the arrow operator for next node.
class Node {
int data;
Node * next;
};
int main() {
Node * node1, node2; // why make it a pointer
Node node3, node4; // Why dont people leave it has non pointer,
because you already have Node* next in the class.
}
Pointers play well with dynamic allocation. You can continue using the object through pointers until you purposefully free it. Automatic objects on the other hand, get destroyed at the end of the scope leaving all pointers (and references!1) to them dangling.
If you know that you won't use any of the pointers outside the scope that contains the object itself (this is likely true for your example in main()), then go right ahead and use an automatic object.
But one final complication is that if one of the pointers is a "smart" pointer that knows how to free the object it points to, you have to create the attached object using the matching allocation function. Attempting to free an automatic (scoped)2 object will result only in misery.
1 The oft-repeated statements like "a reference is equivalent to the object itself" and "a well-defined program cannot create an invalid reference" are horribly wrong but that's too long a discussion to have here.
2 Misery also accompanies trying to free an object which is static or a member subobject or dynamically allocated using a different allocator.
You can do this for some educational purpose.
class Node {
public:
int data;
Node * next;
Node(int d, Node *nextNode = NULL) :data(d), next(nextNode) {}
Node() {}
};
int main() {
Node node3, node4(20);
node3.data = 10;
node3.next = &node4;
std::cout << node3.data << " " << node3.next->data << std::endl;
}
But in real world, in creation of linked linked, you don't know when you have to create a list. In your case its a small class, but consider if it a big class with several complex data structure. If you go in this way, unnecessarily you will create a object on stack.
It will also create ambiguity while deleting memory, you will have to take a special care. In fact, you will not be able to remove memory for your first node until execution goes out of memory.
now here is one big issue, If you are passing this list to some other function(may be creating a list in a function and returning it to caller), this first Node will go out of scope and the memory allocated to your list will be leaked.
Hope I cleared your doubt.
Try to change it into a Node object and compile the code. There should be a compilation error saying that it is an incomplete type. This is because the next field is creating an infinite loop and the compiler cannot calculate how big that field is supposed to be.
A pointer is a reference to a place in memory, since each node should reference the other node and not store its value directly, because if it would store a value you need to update it each time the other node is updated.
One can also use a pointer to allocate memory in the "heap" with the "new" keyword(dynamic storage), otherwise it could be stored in the "stack"(automatic storage), which has a very limited memory(you can get a stack overflow).
I'm learning C++ and I am trying to understand when to assign a pointer to a base class to an object created using the new keyword as opposed to creating an object normally and setting a pointer equal to the address of the object?
Effectively is there any difference in the methods implemented below.
#include<iostream>
using namespace std;
class Base
{
public:
virtual void show() { cout<<" In Base \n"; }
};
class Derived: public Base
{
public:
void show() { cout<<"In Derived \n"; }
};
int main(void)
{
Base *bp = new Derived();
bp->show();
Derived d1;
Base *bp = &d1;
bp->show();
return 0;
}
The formula is pretty simple:
1) If you use new, you are allocating memory (on the heap) for the newly created object. Your variable (pointer) points to that memory region. You should delete the created object (through its pointer) at some point yourself.
Referring to your example:
Base *bp = new Derived();
bp->show();
delete bp;
bp = NULL; // this is good practice, NULLing the pointer after deleting
// the referenced memory
2) If you just have a (non pointer) local variable, then the memory is automatically allocated for it on the function's stack. Memory is automatically freed when the execution point leaves that function. If you just have a pointer to a local variable, you don't need to free (delete) the memory.
Derived d1;
Base *bp = &d1;
bp->show();
// no need to free
However, it's better to do just this:
Derived d1;
d1.show();
Simpler.
The only difference - in your code at least - is in how lifetime is managed,
The first object is dynamically allocated (created when the programmer chooses, at run time) and will continue to exist until a corresponding delete expression. Since there is no delete expression, the object will never be released (although modern operating systems will typically reclaim memory as the program exits, that is not strictly required). If you were to add a statement that does delete bp, it will have undefined behaviour, since Base does not have a virtual destructor.
The second case is a variable of automatic storage duration, so ceases to exist when the enclosing block ends. It will cease to exist as main() returns.
In your code as shown, there will be no visible difference in output. That does not mean the two cases work the same way.
The difference is in how your memory is being allocated. If you use your first definition, you are using memory from the heap, which is essentially boundless (within system constraints obviously), if you allocate the object the second way you are using the stack which has a finite set of memory allocated to it for a given process running it. An example where this could become an issue is when you are creating a ton of objects on your stack (E.g., for a video game) and that stack becomes full, then you will get a stack over flow error returned. This has happened to me once, and then you must leverage the power and knowledge of the heap.
My question is mostly theoretical. Suppose we have a class
class A{
private:
int * a;
int b;
private:
A(){
a = new int[100];
b = 100;
}
~A(){
delete [] a;
}
}
As far as I know if we create object of type A dynamically (A * a = new A()) the memory for this object will allocate in heap and if I use (A a) it will be created on stack (A a). In the case when object is created on stack memory for variable a will allocated on heap and in case when we allocated object on heap memory for object b will be allocated on stack. First question for me to be sure: am I right?
And second question would it be more efficient to store all members of class in heap memory or stack memory eg?
class A{
private:
int * a;
int * b;
private:
A(){
a = new int[100];
b = new int(100);
}
~A(){
delete [] a;
delete b;
}
}
When I said efficient I mean that all data about class member will be storing near each other in memory in heap or stack (actually I'm not sure that is correct that they will be storing near each other).
First off there is no heap or stack in C++. Instead we have automatic storage duration and dynamic storage duration. A object with automatic storage duration is a scoped object. When it goes out of scope it is automatically cleaned up. An object with dynamic storage duration on the other hand is not bound by its scope. Its lifetime only ends when it is explicitly ended by the program (generally this means calling delete).
Now in A you have one object stored with automatic storage duration , b, and one with dynamic storage duration ,a. This means that b will live wherever the A instance lives. a also lives within the A instance but the memory it points to will reside somewhere in memory but we do not know where. When the instance is destroyed b will automatically be cleaned up but a will required special handling in the destructor otherwise the memory will leak. You can visualize it like
A
+------+ +----------+
| a->+---| 100 ints |
| b | +----------+
+------+
As far as efficiency goes as Some programmer dude mentioned you should not really worry about that. You should use the types that you fell is right for the job. Once you have it up and running then you can profile it to find where the bottle neck is. If you see too many cache misses because of using pointers then you can look at trying to localize the data to the class itself.
I would also like to mention then if you find yourself writting some_type* name = new/new[] then you should consider using a std:unique_ptr<some_type>/std:unique_ptr<some_type[]> or std::vector<some_type>.
No, you are not exactly correct.
a and b are variables inside your object.
They both extends the size of your class - at least by the size of sizeof(int*).
Depending of the way you constructed your object, the memory for this variables is allocated on stack or heap as you already mentioned:
new A/int/etc allocates memory on heap
A/int/etc. var allocates memory on stack
The thing you miss is that your data allocated in constructor
a = new int[100];
is not a part of your class object. It is some external data. In your class object you have only a int* member (with a size of 4-8 bytes, depending on architecture) that points to this data.
First of all the downside to the member raw pointers (for ex. MyClass) is it forces to #include the header where MyClass is declared. This can lead to slow compilation. To solve you can use smart pointers with forward declarations.
And second question would it be more efficient to store all members of class in heap memory or stack memory eg?
Typically best to use pointer only when necessary. You should generally declare the members as values in class. It will be local, there will be less chance for errors, fewer allocations, ultimately fewer things that could go wrong, and the compiler can always know it is there at a specified offset so... it helps optimization and binary reduction at a few levels.
I am trying to understand the difference between the stack and heap memory, and this question on SO as well as this explanation did a pretty good job explaining the basics.
In the second explanation however, I came across an example to which I have a specific question, the example is this:
It is explained that the object m is allocated on the heap, I am just wondering if this is the full story. According to my understanding, the object itself indeed is allocated on the heap as the new keyword has been used for its instantiation.
However, isn't it that the pointer to object m is on the same time allocated on the stack? Otherwise, how would the object itself, which of course is sitting in the heap be accessed. I feel like for the sake of completeness, this should have been mentioned in this tutorial, leaving it out causes a bit of confusion to me, so I hope someone can clear this up and tell me that I am right with my understanding that this example should have basically two statements that would have to say:
1. a pointer to object m has been allocated on the stack
2. the object m itself (so the data that it carries, as well as access to its methods) has been allocated on the heap
Your understanding may be correct, but the statements are wrong:
A pointer to object m has been allocated on the stack.
m is the pointer. It is on the stack. Perhaps you meant pointer to a Member object.
The object m itself (the data that it carries, as well as access to its methods) has been allocated on the heap.
Correct would be to say the object pointed by m is created on the heap
In general, any function/method local object and function parameters are created on the stack. Since m is a function local object, it is on the stack, but the object pointed to by m is on the heap.
"stack" and "heap" are general programming jargon. In particular , no storage is required to be managed internally via a stack or a heap data structure.
C++ has the following storage classes
static
automatic
dynamic
thread
Roughly, dynamic corresponds to "heap", and automatic corresponds to "stack".
Moving onto your question: a pointer can be created in any of these four storage classes; and objects being pointed to can also be in any of these storage classes. Some examples:
void func()
{
int *p = new int; // automatic pointer to dynamic object
int q; // automatic object
int *r = &q; // automatic pointer to automatic object
static int *s = p; // static pointer to dynamic object
static int *s = r; // static pointer to automatic object (bad idea)
thread_local int **t = &s; // thread pointer to static object
}
Named variables declared with no specifier are automatic if within a function, or static otherwise.
When you declare a variable in a function, it always goes on the stack. So your variable Member* m is created on the stack. Note that by itself, m is just a pointer; it doesn't point to anything. You can use it to point to an object on either the stack or heap, or to nothing at all.
Declaring a variable in a class or struct is different -- those go where ever the class or struct is instantiated.
To create something on the heap, you use new or std::malloc (or their variants). In your example, you create an object on the heap using new and assign its address to m. Objects on the heap need to be released to avoid memory leaks. If allocated using new, you need to use delete; if allocated using std::malloc, you need to use std::free. The better approach is usually to use a "smart pointer", which is an object that holds a pointer and has a destructor that releases it.
Yes, the pointer is allocated on the stack but the object that pointer points to is allocated on the heap. You're correct.
However, isn't it that the pointer to object m is on the same time
allocated on the stack?
I suppose you meant the Member object. The pointer is allocated on the stack and will last there for the entire duration of the function (or its scope). After that, the code might still work:
#include <iostream>
using namespace std;
struct Object {
int somedata;
};
Object** globalPtrToPtr; // This is into another area called
// "data segment", could be heap or stack
void function() {
Object* pointerOnTheStack = new Object;
globalPtrToPtr = &pointerOnTheStack;
cout << "*globalPtrToPtr = " << *globalPtrToPtr << endl;
} // pointerOnTheStack is NO LONGER valid after the function exits
int main() {
// This can give an access violation,
// a different value after the pointer destruction
// or even the same value as before, randomly - Undefined Behavior
cout << "*globalPtrToPtr = " << *globalPtrToPtr << endl;
return 0;
}
http://ideone.com/BwUVgm
The above code stores the address of a pointer residing on the stack (and leaks memory too because it doesn't free Object's allocated memory with delete).
Since after exiting the function the pointer is "destroyed" (i.e. its memory can be used for whatever pleases the program), you can no longer safely access it.
The above program can either: run properly, crash or give you a different result. Accessing freed or deallocated memory is called undefined behavior.
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!