Can some experienced programmer here explain in details what's a stack and what's a heap like in a simplified way, cause what I usually find from searching is not what I want , like what is the stack relation with functions and variables vs the heap? Alot of these thing just confuse me XD I hope someone has a nice answer ^^
Hi there, I am not sure to understand your question but I am going to try to answer it anyway. The heap and the stacks are different parts of the memory of your computer that C++ can use to store data(variables, objects...). They are both parts of your RAM but store data in different ways. Data stored on the stack are accessible very quickly but the downside is that the stack has memory limits. If you store too much data on the stack it will result in a Stack Overflow. Generally, data stored on the stack are basic local variables, objects and functions. The stack stores data 'on top of each other'. Here's an example:
1 2 3 4 5 6 7 8 9
int main()
{
int x = 10; // x is allocated on the stack.
int y = 20; //y is also allocated on the stack but on top of x.
return 0;
}
Once the program ends, x and y are deleted from the stack in reverse order(y will be destroyed first).
The heap is like a huge pool of memory. It is slower than the stack but its size is only limited by the amount of memory that the computer has access to. Data stored on the heap are typically larger and can stay there even after the program has stopped. This is typically something we want to avoid because we don't want to flood the user's memory with data that is being unused. You can allocate memory on the heap by using the keyword new. You need to use to use the keyword delete to free the memory you used. Here's an example:
1 2 3 4 5 6 7 8 9 10 11
int main()
{
int* x = newint; // A pointer x that points to an integer on the heap.
Foo* foo = new Foo(); //A pointer foo that points to a Foo object on the heap.
delete x;
delete foo; // Free the memory we used on the heap.
return 0;
}
We allocated memory on the heap for an integer and for an object Foo using the new keyword. We then freed that memory using the delete keyword. In C++, you only can access and modify the memory on the heap using a pointer because unlike the stack, the heap memory is not already allocated to your program.
Also, note with the STL, it stores it's data on the heap automatically, so there is no need for one to worry about explicitly putting it there with new One can do a lot just by using the STL. The other advantage is not having to manually doing your own memory management.
The problem with new is that if something throws an exception, the delete is never reached. That is why new and delete should be avoided, unless you are a library writer for example.
Just wanting to obtain a pointer is another reason not to use new.
C++ also has smart pointers, std::unique_ptr for example. These don't suffer the same problems as new allocated pointers.
C++ also have things like copy elision, reference and move semantics, so there may not be a need to use pointers at all.
Yes, of course :+) I did say "may" but should have said "often". And one might not need a pointer, where copy elision, references or implicit move semantics (as in growing a vector) are being used.
Can one do polymorphism with std::reference_wrapper ?
hey tIM, you're being magnanimous - i think cubbi has settled this discussion in your favor!
but where I think raw pointers might yet have a role to play is linked lists - we've seen previously on this forum - std::shared_ptr's create circular references and its difficult to make std::unique_ptr's give up ownership while traversing lists, for e.g to delete a particular node. I have a rough program here in case anyone's interested - couldn't make the deleteNode() method work with std::unique_ptr: http://coliru.stacked-crooked.com/a/c003b7b4a006eb2b
I took an inordinately long time to reply, so I didn't see Cubbi's reply until today. I was trying to look for an example of polymorphism with a container of std::reference_wrapper. I suspect it would be easier to have a container of smart pointer.
Anyway, the motivation for my original reply was to steer the OP away from thinking they need to use new everywhere.
> I suspect it would be easier to have a container of smart pointer.
No, not really. If dynamic storage duration is not a requirement, wrapped references would be simpler.
Note: the overloaded call operator can be invoked directly via the wrapper; for others, we would have to go through the underlying reference retrieved with get()