where? heap or stack?

J

Jonas Rundberg

Hi
I just started with c++ and I'm a little bit confused where stuff
go...
Assume we have a class:

class test {
private:
int arr[100];
};

That is, I assume that 'arr' is allocated on the stack, since I don't
use new.
But where is this array allocated if I allocate a test object in the
heap?
I.e.
test t = new test;
The object will reside in the heap so therefore the 'arr' will be in
the heap too?

Are there any pro/cons to heap/stack allocate member variables (of non
trivial type)?

Thanks
Jonas
 
J

Jeff Schwab

Jonas said:
Hi
I just started with c++ and I'm a little bit confused where stuff
go...
Assume we have a class:

class test {
private:
int arr[100];
};

That is, I assume that 'arr' is allocated on the stack, since I don't
use new.

It hasn't been allocated at all. So far, you've defined a new type, but
allocated nothing.
But where is this array allocated if I allocate a test object in the
heap?
I.e.
test t = new test;
The object will reside in the heap so therefore the 'arr' will be in
the heap too?

Yes. Careful about calling it "heap," though; "stack" and "heap" in C++
refer to standard data structures, not to regions of memory.
Are there any pro/cons to heap/stack allocate member variables (of non
trivial type)?

http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&q=heap+stack+better&btnG=Search

Basically, prefer the stack when you can, since it tends to be faster
and less error-prone. For very large objects, objects that must
out-live the scope of their definitions, and collections of unknown
size, use the heap.
 
J

Jeff Schwab

Jeff said:
For very large objects, objects that must
out-live the scope of their definitions, and collections of unknown
size, use the heap.

Unknown at compile time, that is.
 
T

Thomas Matthews

Jonas said:
Hi
I just started with c++ and I'm a little bit confused where stuff
go...
Assume we have a class:

class test {
private:
int arr[100];
};

That is, I assume that 'arr' is allocated on the stack, since I don't
use new.
But where is this array allocated if I allocate a test object in the
heap?
I.e.
test t = new test;
The object will reside in the heap so therefore the 'arr' will be in
the heap too?

Are there any pro/cons to heap/stack allocate member variables (of non
trivial type)?

Thanks
Jonas

First off, according to the ANSI/ISO standard, there is no
requirement for a heap or a stack.

But I will refer to the "heap" as _dynamic_memory_. Dynamic
memory is memory that is allocated by a program during
run-time and the program controls the life-span of these objects.
This area of memory is accessed by the new operator and *alloc
functions.

Lifetime of variables: When the program creates it,
until the program destroys it.

Example:
test * pointer;
//...
pointer = new test;


There is also another region of memory where automatic,
and static variables are placed. Objects are allocated
in this memory by the compiler before the "main" function
is executed. Global variables, variables declared in
static with file scope, variables declared as static in
functions or blocks are allocated from this memory area.

Lifetime of variables: Program start to program end.

Example:
test global_test_variable;
void Example1(void)
{
static test static_function_variable;
return;
}


The next common area of memory is where local function
and block variables are stored. These variables
are allocated before the block or function is executed
and destroyed upon exit of the function or block.

Lifetime of variables: Start of function or block
until the end of the function
or block.

Example:
void Example2(void)
{
test a_local_variable;

for (unsigned int i = 0; i < 10; ++i)
{
test a_block_variable;
a_block_variable.a = i;
}
return;
}


In your example, the identifier, "arr", names a
field, or member, of the class "test". This member
will always be a part of the class. All variables
of type "test" will have the "arr" member; regardless
of where the variable or instance resides.

There are two common usages for allocation from the
"heap": huge variables and variables whose size or
need are determined at run-time. Many compilers have
a fixed sized area for the automatic and "stack"
memory areas. They usually limit the size of the
"heap" to the amount of memory left in the platform.
Thus the heap is usually larger than the other two
memory areas.

Often times, objects need to be created during run-time.
The quantity or size is determined by factors outside
of your program. Examples: databases, messages,
image processing, audio processing and data logging.
With audio processing, one doesn't know the quantity
of data until runtime. With message processing, the
program doesn't know which message it will receive
and when.


--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
L

Leor Zolman

Yes. Careful about calling it "heap," though; "stack" and "heap" in C++
refer to standard data structures, not to regions of memory.

Interesting this issue should just now come up, as I was wondering myself
about it while reading through Eckel/Allison's _Thinking in C++ Volume II_.
Throughout the book, they use the word "heap" synonymously with "free
store". IOW, instead of saying "allocated dynamically" or even "allocated
on/from the free store", they consistently say "from the heap", use the
term "heap memory", and even name a utility class for monitoring use of
new/delete "TraceHeap".

Now I'm used to seeing this wording being picked on, but hasn't it in fact
become effectively idiomatic to say "allocated on the heap" when you simply
mean dynamically? Sort of like the word "momentarily" has now,
unfortunately, become effectively synonymous with "in a moment"? In
reality, how often is the use of the word "heap" /really/ going to be
ambiguous when it pops up in discussions like this? I'm not happy about it,
but I'd vote to bite the bullet and just let people say "heap" unmolested
unless it really isn't clear what they're talking about...
-leor
 
J

Jeff Schwab

Leor said:
Interesting this issue should just now come up, as I was wondering myself
about it while reading through Eckel/Allison's _Thinking in C++ Volume II_.
Throughout the book, they use the word "heap" synonymously with "free
store". IOW, instead of saying "allocated dynamically" or even "allocated
on/from the free store", they consistently say "from the heap", use the
term "heap memory", and even name a utility class for monitoring use of
new/delete "TraceHeap".

Now I'm used to seeing this wording being picked on, but hasn't it in fact
become effectively idiomatic to say "allocated on the heap" when you simply
mean dynamically? Sort of like the word "momentarily" has now,
unfortunately, become effectively synonymous with "in a moment"? In
reality, how often is the use of the word "heap" /really/ going to be
ambiguous when it pops up in discussions like this? I'm not happy about it,
but I'd vote to bite the bullet and just let people say "heap" unmolested
unless it really isn't clear what they're talking about...

You're absolutely right. The FAQ for this group even refers to the
stack & the heap in the idiomatic way. Unfortunately, when one uses
these terms in a news group posting, someone likely will get very huffy
and say something pedantic unless you beat them to the punch. I try to
do nip such complaints in the bud in a more humane way than some folks
might.

Of course, in "real world" conversations, development is usually being
done for well-known platforms, so I can point to documentation that
explains the free store really is a heap, and that function-scoped
variables really are on a stack. :)
 
L

Leor Zolman

You're absolutely right. The FAQ for this group even refers to the
stack & the heap in the idiomatic way. Unfortunately, when one uses
these terms in a news group posting, someone likely will get very huffy
and say something pedantic unless you beat them to the punch. I try to
do nip such complaints in the bud in a more humane way than some folks
might.

Of course, in "real world" conversations, development is usually being
done for well-known platforms, so I can point to documentation that
explains the free store really is a heap, and that function-scoped
variables really are on a stack. :)

One way to deal with this is just to use the "proper" terminology in
responses. Looking back over some of my replies, I've tended to just stick
with the OP's terminology (if they say "heap", I say "heap" too) most of
the time, while occasionally switching. Now that I'm focused on the issue
more, it may work well to note the change-over, e.g:

OP: blah blah blah on the heap blah blah blah
me: blah blah blah on the free store (heap) blah blah blah ...
and then just use free store, or "dynamic", from then on.

There may be no perfect solution, but there are really enough bigger fish
to fry (and I'm addressing the entire group with this, not just you, Jeff,
and that was also the case before) that I suggest we all just let this
little one go if we catch it ;-)
-leor
 
C

Claudio Puviani

Leor Zolman said:
Interesting this issue should just now come up, as I was wondering myself
about it while reading through Eckel/Allison's _Thinking in C++ Volume II_.
Throughout the book, they use the word "heap" synonymously with "free
store". IOW, instead of saying "allocated dynamically" or even "allocated
on/from the free store", they consistently say "from the heap", use the
term "heap memory", and even name a utility class for monitoring use of
new/delete "TraceHeap".

Herb Sutter, in GotW #9 (and subsequently in "Exceptional C++"), makes a
distinction between "heap" and "free store" (hopefully, Herb won't sue me for
copying and pasting):

The following summarizes a C++ program's major distinct memory areas.
Note that some of the names (e.g., "heap") do not appear as such in
the draft.


Memory Area Characteristics and Object Lifetimes
-------------- ------------------------------------------------

Const Data The const data area stores string literals and
other data whose values are known at compile
time. No objects of class type can exist in
this area. All data in this area is available
during the entire lifetime of the program.

Further, all of this data is read-only, and the
results of trying to modify it are undefined.
This is in part because even the underlying
storage format is subject to arbitrary
optimization by the implementation. For
example, a particular compiler may store string
literals in overlapping objects if it wants to.


Stack The stack stores automatic variables. Typically
allocation is much faster than for dynamic
storage (heap or free store) because a memory
allocation involves only pointer increment
rather than more complex management. Objects
are constructed immediately after memory is
allocated and destroyed immediately before
memory is deallocated, so there is no
opportunity for programmers to directly
manipulate allocated but uninitialized stack
space (barring willful tampering using explicit
dtors and placement new).


Free Store The free store is one of the two dynamic memory
areas, allocated/freed by new/delete. Object
lifetime can be less than the time the storage
is allocated; that is, free store objects can
have memory allocated without being immediately
initialized, and can be destroyed without the
memory being immediately deallocated. During
the period when the storage is allocated but
outside the object's lifetime, the storage may
be accessed and manipulated through a void* but
none of the proto-object's nonstatic members or
member functions may be accessed, have their
addresses taken, or be otherwise manipulated.


Heap The heap is the other dynamic memory area,
allocated/freed by malloc/free and their
variants. Note that while the default global
new and delete might be implemented in terms of
malloc and free by a particular compiler, the
heap is not the same as free store and memory
allocated in one area cannot be safely
deallocated in the other. Memory allocated from
the heap can be used for objects of class type
by placement-new construction and explicit
destruction. If so used, the notes about free
store object lifetime apply similarly here.


Global/Static Global or static variables and objects have
their storage allocated at program startup, but
may not be initialized until after the program
has begun executing. For instance, a static
variable in a function is initialized only the
first time program execution passes through its
definition. The order of initialization of
global variables across translation units is not
defined, and special care is needed to manage
dependencies between global objects (including
class statics). As always, uninitialized proto-
objects' storage may be accessed and manipulated
through a void* but no nonstatic members or
member functions may be used or referenced
outside the object's actual lifetime.


Note about Heap vs. Free Store: We distinguish between "heap" and
"free store" because the draft deliberately leaves unspecified the
question of whether these two areas are related. For example,
when memory is deallocated via operator delete, 18.4.1.1 states:

It is unspecified under what conditions part or all of such
reclaimed storage is allocated by a subsequent call to operator new
or any of calloc, malloc, or realloc, declared in <cstdlib>.

Similarly, it is unspecified whether new/delete is implemented in
terms of malloc/free or vice versa in a given implementation.
Effectively, the two areas behave differently and are accessed
differently -- so be sure to use them differently!
 
M

Mike

Free Store The free store is one of the two dynamic memory
areas, allocated/freed by new/delete. Object
lifetime can be less than the time the storage
is allocated; that is, free store objects can
have memory allocated without being immediately
initialized, and can be destroyed without the
memory being immediately deallocated.


I always understood 'new' as something that calls a constructor apart
from (m)allocating memory. And this snippet says that free store objects
are created using 'new' , but need not be initialised immediately ? (
which constructor is supposed to take care ?)

Maybe I'm totally missing out on something
 
L

Leor Zolman

Herb Sutter, in GotW #9 (and subsequently in "Exceptional C++"), makes a
distinction between "heap" and "free store" (hopefully, Herb won't sue me for
copying and pasting):

The following summarizes a C++ program's major distinct memory areas.
Note that some of the names (e.g., "heap") do not appear as such in
the draft.

[Herb's summary snipped]
Note about Heap vs. Free Store: We distinguish between "heap" and
"free store" because the draft deliberately leaves unspecified the
question of whether these two areas are related. For example,
when memory is deallocated via operator delete, 18.4.1.1 states:

It is unspecified under what conditions part or all of such
reclaimed storage is allocated by a subsequent call to operator new
or any of calloc, malloc, or realloc, declared in <cstdlib>.

Similarly, it is unspecified whether new/delete is implemented in
terms of malloc/free or vice versa in a given implementation.
Effectively, the two areas behave differently and are accessed
differently -- so be sure to use them differently!

All of which I have no problem with; the point I was trying to make is that
this distinction is usually /beside the point/ in the context of many
(most?) questions that arise concerning dynamic memory.

A continuous challenge in newsgroup postings (esp. responses), and one I
always struggle with personally, is to know how much detail to go into.
Often you just can't tell without the proverbial crystal ball; thus, my
instinct is to err on the side of providing /less/ detail, and not to open
Pandora's box if it isn't clear the OP has requested it opened.

Not to beat a dead horse (or further pummel Jeff), but take a look at the
subject of the OP's question in this thread, and at the body of that
question. Do you really think this particular OP really needed to know that
the "heap" was something other than the free store (maybe)? I don't think
so. He may not even have been aware that there was any such thing as
"malloc" and "free"; certainly, someone learning C++ the modern way would
have no need to know about those functions (yet). This is precisely where a
little bit of restraint would, IMHO, go a long way.
-leor
 
C

Claudio Puviani

Mike said:
I always understood 'new' as something that calls a constructor apart
from (m)allocating memory. And this snippet says that free store objects
are created using 'new' , but need not be initialised immediately ? (
which constructor is supposed to take care ?)

It may make things confusing, but are both a set of operator 'new' signatures AND
a family of functions called 'new' that only allocate raw memory. Operator 'new'
calls function 'new' and then the created instance's constructor. Sutter was
refering to the function that allocates raw memory, not the operator.

Claudio Puviani
 
C

Claudio Puviani

Leor Zolman said:
Herb Sutter, in GotW #9 (and subsequently in "Exceptional C++"), makes a
distinction between "heap" and "free store" (hopefully, Herb won't sue me for
copying and pasting):

The following summarizes a C++ program's major distinct memory areas.
Note that some of the names (e.g., "heap") do not appear as such in
the draft.

[Herb's summary snipped]
Note about Heap vs. Free Store: We distinguish between "heap" and
"free store" because the draft deliberately leaves unspecified the
question of whether these two areas are related. For example,
when memory is deallocated via operator delete, 18.4.1.1 states:

It is unspecified under what conditions part or all of such
reclaimed storage is allocated by a subsequent call to operator new
or any of calloc, malloc, or realloc, declared in <cstdlib>.

Similarly, it is unspecified whether new/delete is implemented in
terms of malloc/free or vice versa in a given implementation.
Effectively, the two areas behave differently and are accessed
differently -- so be sure to use them differently!

All of which I have no problem with; the point I was trying to make is that
this distinction is usually /beside the point/ in the context of many
(most?) questions that arise concerning dynamic memory.

But it WAS in context with respect to the statement you made that Eckel makes no
distinction between 'heap' and 'free store'.
A continuous challenge in newsgroup postings (esp. responses), and one I
always struggle with personally, is to know how much detail to go into.
Often you just can't tell without the proverbial crystal ball; thus, my
instinct is to err on the side of providing /less/ detail, and not to open
Pandora's box if it isn't clear the OP has requested it opened.

That's a personal choice. My preference is to give more detail if giving less
detail creates an ambiguity, as was the case with 'heap' and 'free store'.
Not to beat a dead horse (or further pummel Jeff), but take a look at the
subject of the OP's question in this thread, and at the body of that
question. Do you really think this particular OP really needed to know that
the "heap" was something other than the free store (maybe)? I don't think
so.

I disagree. If the OP was ready to discuss the distinctions between 'heap' and
'stack', including the other storage classes in the conversation is completely
appropriate.
He may not even have been aware that there was any such thing as
"malloc" and "free"; certainly, someone learning C++ the modern way would
have no need to know about those functions (yet).

Again, we disagree. I think the OP is better off knowing about them so that if he
encounters them, he'll be aware of what he's facing.
This is precisely where a little bit of restraint would, IMHO, go a long way.

I was restrained. I didn't go into custom allocators or exception considerations
during allocations or any other tangential topics. The OP's question, whether he
realized it or not, was about storage classes and now he knows more about the
topic.

Claudio Puviani
 
E

E. Robert Tisdale

Claudio Puviani wrote:

Herb Sutter, in GotW #9 (and subsequently in "Exceptional C++"),
makes a distinction between "heap" and "free store"

Unfortunately, Herb is *wrong*.
(hopefully, Herb won't sue me for copying and pasting):


The following summarizes a C++ program's major distinct memory areas.
Note that some of the names (e.g., "heap") do not appear as such in
the draft.


Memory Area Characteristics and Object Lifetimes
-------------- ------------------------------------------------

Const Data The const data area stores string literals and
other data whose values are known at compile
time. No objects of class type can exist in
this area. All data in this area is available
during the entire lifetime of the program.

Further, all of this data is read-only, and the
results of trying to modify it are undefined.
This is in part because even the underlying
storage format is subject to arbitrary
optimization by the implementation. For
example, a particular compiler may store string
literals in overlapping objects if it wants to.


Stack The stack stores automatic variables. Typically
allocation is much faster than for dynamic
storage (heap or free store) because a memory
allocation involves only pointer increment
rather than more complex management. Objects
are constructed immediately after memory is
allocated and destroyed immediately before
memory is deallocated, so there is no
opportunity for programmers to directly
manipulate allocated but uninitialized stack
space (barring willful tampering using explicit
dtors and placement new).

C++ does *not* require a program stack to implement free storage
but free storage is always implemented on the program stack
in all viable implementations so a reference to the stack
in the context of a C++ program is *always* a reference to
the underlying implementation and *not* the language itself.
Free Store The free store is one of the two dynamic memory
areas, allocated/freed by new/delete. Object
lifetime can be less than the time the storage
is allocated; that is, free store objects can
have memory allocated without being immediately
initialized, and can be destroyed without the
memory being immediately deallocated. During
the period when the storage is allocated but
outside the object's lifetime, the storage may
be accessed and manipulated through a void* but
none of the proto-object's nonstatic members or
member functions may be accessed, have their
addresses taken, or be otherwise manipulated.


Heap The heap is the other dynamic memory area,
allocated/freed by malloc/free and their
variants. Note that while the default global
new and delete might be implemented in terms of
malloc and free by a particular compiler, the
heap is not the same as free store and memory
allocated in one area cannot be safely
deallocated in the other. Memory allocated from
the heap can be used for objects of class type
by placement-new construction and explicit
destruction. If so used, the notes about free
store object lifetime apply similarly here.

If there is a data structure called "heap",
it is feature of your implementation and *not* standard C or C++.
There is *no* requirement that new/delete malloc/free
manage different data structures.
In a typical implementation, new and delete are implemented
by calling malloc and free respectively
and they manage the same data structure.

Free storage is exactly what is meant by the free storage.
It is [virtual] memory which has not yet been [re]allocated
for use by your program. In the typical implementation,
it is free memory below the bottom of the text (code) segment
and above the top of the program (process) stack.
Generally, the stack grows up into free storage.
In the typical implementation, the remainder of free storage
is managed by a *free list*. The term heap was coined
by IBM programmers as a whimsical name
for their implementation of a free list.
It is a *pun* which contrasts it with the term stack.
Global/Static Global or static variables and objects have
their storage allocated at program startup, but
may not be initialized until after the program
has begun executing. For instance, a static
variable in a function is initialized only the
first time program execution passes through its
definition. The order of initialization of
global variables across translation units is not
defined, and special care is needed to manage
dependencies between global objects (including
class statics). As always, uninitialized proto-
objects' storage may be accessed and manipulated
through a void* but no nonstatic members or
member functions may be used or referenced
outside the object's actual lifetime.

The location of constant or variable global or static objects
is left up to the implementation. Constants may be and often are
embedded in the text (code) segment and small integral constants
may be loaded immediately out of the instruction stream.
Variables may be placed in a special data segment right after
the text segment. at the bottom of the program stack
or even allocated from free storage.
 
L

Leor Zolman

But it WAS in context with respect to the statement you made that Eckel makes no
distinction between 'heap' and 'free store'.

Perhaps you misconstrued my point; I wasn't bringing up the use of "heap"
in the book to parade it as evidence of equivalence between "heap" and
"free store". I don't believe for a second that Chuck Allison and Bruce
Eckel aren't aware of the distinction. Rather, I believe a conscious
decision was made to downplay that distinction, perhaps because to bring it
up just injects gratuitous complexity in cases when there's no need to
worry about it.

If you thought I was arguing that heap and free store are the same, then I
can understand your citing Herb's writing. The context I was referring to
above, however, was the OP's post, not the Eckel/Allison book.
That's a personal choice. My preference is to give more detail if giving less
detail creates an ambiguity, as was the case with 'heap' and 'free store'.

Okay, I respect where you're coming from. Until seeing the treatment that
this terminology got in the book, I would have been inclined to agree with
you in principle. But now I'm leaning toward avoidance of bringing up any
distinction between heap and free store in a thread unless some question
truly specific to that distinction arises.
I disagree. If the OP was ready to discuss the distinctions between 'heap' and
'stack', including the other storage classes in the conversation is completely
appropriate.

This is where the crystal ball comes in handy. I look into mine and see a
question concerning the difference between static and dynamic allocation at
an elementary level; you may look and see deeper questions. We must each
follow our own muse, I guess.
Again, we disagree. I think the OP is better off knowing about them so that if he
encounters them, he'll be aware of what he's facing.


I was restrained. I didn't go into custom allocators or exception considerations
during allocations or any other tangential topics. The OP's question, whether he
realized it or not, was about storage classes and now he knows more about the
topic.

Okay, Claudio; I have considerable respect for your postings and
experience, while I'm a relative newbie at all this. I just try to put
something out when I think the differing perspective might possibly end up
doing some good.

No worries,
-leor
 
C

Claudio Puviani

Leor Zolman said:
Okay, Claudio; I have considerable respect for your postings and
experience, while I'm a relative newbie at all this.

Um. Leor, you wrote one of the first C compilers that I used. Please don't refer
to yourself as a newbie. In relative terms, I'm the newbie of the pair. :)

Claudio Puviani
 
C

Claudio Puviani

E. Robert Tisdale said:
Claudio said:
Herb Sutter, in GotW #9 (and subsequently in "Exceptional C++"),
makes a distinction between "heap" and "free store"

Unfortunately, Herb is *wrong*.

[rest of ERT's habitual trolling snipped]

That's the problem with switching to a new computer. There's always one person
you forget to move to the killfile.

Claudio Puviani
 
L

Leor Zolman

Um. Leor, you wrote one of the first C compilers that I used. Please don't refer
to yourself as a newbie. In relative terms, I'm the newbie of the pair. :)

Thanks, but if you recall the details of that particular implementation,
that alone hardly qualifies me to dispense advice on modern C++, or even C
for that matter...but I try anyway, while trying to get up-to-speed on
things like Standards decryption. And optimizing the performance of that
crystal ball I mentioned earlier wrt interpretation of posted questions.
-leor
 
M

Michiel Salters

E. Robert Tisdale said:
Claudio Puviani wrote:
If there is a data structure called "heap",
it is feature of your implementation and *not* standard C or C++.

At least, when you try to correct someone, be correct.
ISO/IEC 14882:1998 [lib.alg.heap.operations] 25.3.6 Heap operations.
Tip: Ctrl-F 'heap'

Regards,
Michiel Salters
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top