Correct me if I'm wrong but...

Each time I declare an object without assigning it a value, I am instantiating it (so long as the valid constructors is called upon doing so--)

like...

Triangle tri1 (3, 4);

and this object exists on the stackk but only for the duration of its life (which I still don't understand).

But if I do something like this...

Triangle *triPtr = new Triangle (3, 4);

it exists in the heap as dynamically allocated memory. Of course you have to delete (make the memory unallocated, or free) after using it should the program continue to run so you don't cause memory leaks..


My questions are...

-Why use the stack of the space is so limited?
-What are the advantages to using the stack over the heap?
-Is it really so bad to use pointers vs "reference variables?"
-What's the program's efficiency using a stack object over a heap object?
-What exactly is the life of a stack object? I hear that the existence of the object is dependent on its life or its declaration, which still confuses me...

Recommended Answers

All 6 Replies

Well, dynamically allocating space is much slower than stack and the life of a dynamic variable is dependant on when you decide to delete it, however stack variables are deleted at the end of the code block.

>>Why use the stack of the space is so limited?
What makes you think stack space is so limited ? In MS-DOS 6.x and earlier and in some embedded systems that is true, but if you are using *nix or MS-Windows 32-bit compilers stack space isn't really anything to be too concerned about unless you have an object that used several megs of space.


>>What are the advantages to using the stack over the heap?
As I mentioned in your other thread, using pointers unnecessarily can be dangerous to your program. Coders (me too) have spent days trying to find a bug with pointers. Such bugs are often very difficult to find.

>>Is it really so bad to use pointers vs "reference variables?"
No -- but as you found out you have to be very very careful. You can introduce all sorts of memory leaks and bad pointers when you use a lot of pointers. You can easily avoid all those nasty problems by using references.

>>What exactly is the life of a stack object?
The life of a stack object is the life of the function in which the object is declared. All objects are destroyed as part of the function exit code. Memory dynamically allocated to pointers are not auto destroyed, you have to explicitly use the delete operator if new was used to allocate the memory. So if the function returns without deleting the pointer then a memory leak occurs which can not be recovered by the program.

commented: Better than my answer :p +2

Oh I didn't realize that stack space wasn't a problem.

My instructor told me that the stack typically holds less information than the heap. That is the reason why I felt more inclined to learn pointers, but I suppose that isn't entirely true.

I also saw someone else's program where they used reference variables for their assignment and had trouble using them due to the variables being deleted the moment they were assigned... something along the lines of..

/*some code here*/ = Triangle (3, 4);

Where I guess Triangle was being declared, instantiated and then deleted and a null object was returned.

It's also confusing to get used to some of the reference-variable syntax compared to pointer syntax, such as--

Triangle tri (3,4); //looks like a drifting object

as opposed to

Triangle *triPtr = new Triangle(3, 4); //looks like an appropriate assignment.


Also when you redid my program Ancient Dragon I noticed that you declared 3 arrays without assigning them, so I guess the entire array was initialized via the default constructor?

If that's true, can I do something like--

Point myPoints[3] (2, 2);

or maybe

Point myPoints[3] = (2, 2);
--where all of the points are initialized to be (2, 2)?

Sorry for all of the questions but I'm still trying to get my head around appropriate usage of the types.

In all honesty I just want to increase the performance of my programs as I learn. Since passing-by-value includes creating a copy of the actual type (or class) inquestion I figured that learning to use pointers/references would improve performance because instead of dealing with copy-values you can instead use the address provided by the existing data and manipulating the value at will.

One last thing! When would I ever use a reference to a pointer? i.e...

foo(int *&p)
{
//code
}

as opposed to just a pointer--

foo(int *p)
{
//code...
}

since I thought that using a pointer as an argument implied that you were using the actual pointer and not a copy?

Hi all,

though Ancient Dragon has already answered almost every question, I would like to put in my twopenn'orth too.


-Why use the stack of the space is so limited?

Stack is not that limited. One can allocated as much stack as much memory from heap.
Today processors have 32bit stack pointers (e.g. ESP, EBP), what allows one to address some Giga bytes on stack.

-What are the advantages to using the stack over the heap?

Memory on stack will be automatically allocated when variable is to create and
automatically released if variable is no further needed, see below answer to lifetime.
So a programmer does not need care about his variables, except of those which must be
created by new/malloc. Stack is one of the most important data structure or principle in
computer science. Recurrence, especially recursive function calls would really be hard
to implement without stack, or even impossible. On the other hand, every time we don't know the size of an data object when program it, the object must be created, that is its memory must be allocated from heap during runtime. So heap allocation is also essential for programming.


-Is it really so bad to use pointers vs "reference variables?"

I personally think it isn't that bad because there is no difference between them,
except c++ reference variables look more beautiful and accomplish Bjarne Stroustrup's
modern conception of c++.


-What's the program's efficiency using a stack object over a heap object?

Creating stack objects is very simple, for example on assembly level PUSH EAX
creates a 32bit word on stack. Creating a dynamic memory object using new or malloc
requires something more, for example the list of free memory must be scanned to find
an appropriate piece of memory. Generally, creating stack objects is faster than creating
objects by new/malloc. However, when working with already created stack or heap objects
efficiency is rather identical, whereas there are much more different addressing modes
for heap objects contrary to stack.


-What exactly is the life of a stack object? I hear that the existence of the
object is dependent on its life or its declaration, which still confuses me...

All actual parameters from function's parameter lists and all local variables of functions and
more common local variables in program blocks { ... } (except of those allocated by new/malloc) are created on stack by assembly PUSH instructions if function is called and executed or block is entered. The objects on stack become alive. When a function finishes the stack will be automatically cleared in reverse order (last in first out, LIFO principle) by assembly POP instructions or by manipulating the base pointer(EBP). So the objects on stack no longer exist. Their lifetime span from creation on to removing them from stack.

krs,
tesu

>>Triangle tri (3,4); //looks like a drifting object
That is not a reference. Its just simply instantiating a Triangle object and passing the two parameters to the constructor. No references involved here.

If that's true, can I do something like--

Point myPoints[3] (2, 2);

or maybe

Point myPoints[3] = (2, 2);
--where all of the points are initialized to be (2, 2)?

Unfortunately you can't to that.


>>One last thing! When would I ever use a reference to a pointer? i.e...
When you want a function to allocate memory for the calling function's pointer

int foo((int *&p)
{
    p = new int[255];
    for(int i = 0; i < 255; i++)
       p[i] = i;
}

int main()
{
    int* p = 0; // a null pointer
    foo(p);
    for(int i = 0; i < 255; i++)
       p[i] = i;
}

The above can also be done with pointers, but references is a lot cleaner and less complicated

#include <iostream>
#include <ctime>
using std::cout;

void foo(int **p, int n)
{
    *p = new int[n];
    for(int i = 0; i < n; i++)
    {
        (*p)[i] = rand();
    }
}

int main()
{
    int* p = 0; // a null pointer
    int n = 25;
    srand((unsigned int) time(0) );
    foo(&p, n);
    for(int i = 0; i < n; i++)
       cout << p[i] << "\n";
}

Thank you for the clarifications.

Now that I have a better understanding of pointers and reference-variables I'll be able to code much more efficiently.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.