storage locations for different data types

S

smith4894

Hello,

I have a question regarding storage locations for different data types.
For example, dynamically created objects (using "new") are created on
the heap. local objects ( foo() {int x;} ) are on the stack.

1)Where are global non-const objects created?

2)Where are global const objects created?

3)For a function, where are local static objects created? These objects
are not initialized until the function is called, but is storage
allocated for them even if they are never called?

4)For a function, where are const type objects created? on the stack as
well?

5)For a class, where are static class member objects created?

Thanks.
 
M

Mike Wahler

Hello,

I have a question regarding storage locations for different data types.
For example, dynamically created objects (using "new") are created on
the heap. local objects ( foo() {int x;} ) are on the stack.

1)Where are global non-const objects created?

2)Where are global const objects created?

3)For a function, where are local static objects created? These objects
are not initialized until the function is called, but is storage
allocated for them even if they are never called?

4)For a function, where are const type objects created? on the stack as
well?

5)For a class, where are static class member objects created?

None of the above things are specified by the language,
but are implementation-specific details. C++ does not
define or require anything such as 'heap', 'stack', etc.
If you want to know how your particular implementation
handles these things, you'll need to consult its documentation
and/or any available support resources provided by its
vendor.

Anyway, why do you feel you need to know these things?

-Mike
 
M

Maciej Sobczak

Hi,

For example, dynamically created objects (using "new") are created on
the heap. local objects ( foo() {int x;} ) are on the stack.

We say that these objects have the "dynamic storage duration" and the
"automatic storage duration".
1)Where are global non-const objects created?

In some other place, which is a "static storage".
Typically, the memory for all objects with static storage duration
(collectively) is assigned to the process when the program is loaded
into memory. Alternatively, it may be even part of the program (of the
file on disk) itself, but any other strategy is allowed, as long as the
lifetimes of the objects obey the rules. It all depends on implementation.
2)Where are global const objects created?

Same as global non-const. This is static storage.
The const qualifier affects only what you can do with them, not where
they are.
3)For a function, where are local static objects created? These objects
are not initialized until the function is called, but is storage
allocated for them even if they are never called?

Again, static storage.
4)For a function, where are const type objects created? on the stack as
well?

If they are local, then they have automatic storage, on the stack.
Again, the const qualifier does not affect where they are.
5)For a class, where are static class member objects created?

Static storage.
 
E

Emil Kirichev

I'm answering the second question. One way to do this is to make your
base class abstract. That is, make it interface with pure virtual
functions only. All classes that inherit the this class, must implement
the interface (all virtual functions). That way, you declare some in
your program, a function that acepts a pointer to that base class:
some_function(Base* pb); You can pass the address of an object of some
of the child classes, but in that function you have to use only the
interface that is declared in the base class. Every child has its own
implementation of the interface so the image work will be done
according the obejct you pass to the function (gif, jpg, etc.) . That
eliminates the need of checking what image object you are dealing with
(it's called polimorphism). Example:

class Image
{
public:
virual void proccess_image() = 0;
virtual void other_func() = 0;
}

class gif: public Image
{
void proccess_image();
void other_func();
}
void f(Image* pimg)
{
pimg->proccess_imge();
}
in your prog:

gif g;
f(&g);

Hope that's what you want.
 
K

kanze

Maciej said:
(e-mail address removed) wrote:
We say that these objects have the "dynamic storage duration"
and the "automatic storage duration".

In the standard. In practice, heap and stack are usable
synonyms.

Let's not forget, either, that the compiler is not required to
use a contiguous area for any of these. It could very well use
different areas for operator new, operator new[] and malloc, for
example, or allocate stack frames dynamically from the same pool
that malloc uses. (I've actually used a C compiler which did
this.)
In some other place, which is a "static storage". Typically,
the memory for all objects with static storage duration
(collectively) is assigned to the process when the program is
loaded into memory. Alternatively, it may be even part of the
program (of the file on disk) itself, but any other strategy
is allowed, as long as the lifetimes of the objects obey the
rules. It all depends on implementation.

Typically, the compiler will manage two separate "static"
areas, one of which will be write protected when your program
executes (and probably shared amongst multiple instances which
execute simutaneously).
Same as global non-const. This is static storage. The const
qualifier affects only what you can do with them, not where
they are.

With the compilers I use, it depends on the type of the object.
If the object has dynamic initialization or a non-trivial
destructor, it will be allocated with the other static objects.
If it is statically initialized, it will normally be allocated
in the write protected part of the static memory. And if it is
simple enough, and its address is never taken, it might not be
allocated at all.
Again, static storage.

With the same caveats as above.
If they are local, then they have automatic storage, on the
stack. Again, the const qualifier does not affect where they
are.

If the type is simple enough, and the address of the object is
never taken, the object probably will not be allocated at all.
Otherwise, if the object is initialized with a constant
expression, and has a trivial constructor and destructor, it
will most likely be allocated in the write protected static
memory -- most likely, because if the address of the object is
taken, and the function is called recursively, this cannot be
done, since the addresses have to differ.
Static storage.

With all of the above caveats, of course.

And of course, we're only considering single threaded programs
without dynamically loaded objects here.

In fact, of course, the correct answer for all of the above
questions is really: where ever the compiler wants:).
 
A

Allan W

Maciej said:
In some other place, which is a "static storage".
Typically, the memory for all objects with static storage duration
(collectively) is assigned to the process when the program is loaded
into memory. Alternatively, it may be even part of the program (of the
file on disk) itself, but any other strategy is allowed, as long as the
lifetimes of the objects obey the rules. It all depends on implementation.

Same as global non-const. This is static storage.
The const qualifier affects only what you can do with them, not where
they are.

I realize that you're answering a beginner's question, so you don't
want to get too technical. But I think it's important to point out
that const statics CAN be treated differently from non-const statics.
The definitive example is that embedded systems, where const statics
can be put into read-only memory, along with the program code. But it
isn't just embedded systems. A system with protected memory could
put a const object (even a const auto object) into a section of
memory, and then write-lock that section of memory until it's time
to run the destructor.

That's the main reason for the limitations on const_cast: If you cast
a pointer-to-const into a pointer-to-non-const, and the object truely
was a const object, you get undefined behavior.
 
M

Maciej Sobczak

Hi,

In fact, of course, the correct answer for all of the above
questions is really: where ever the compiler wants:).

Yes, and that's why it should be preferred to talk about storage
duration (static / dynamic / automatic) instead of storage "place" (text
or global / heap / stack).

(Interestingly, temporary objects have automatic storage duration, but
they need not be on the "stack" - this applies especially to exception
objects - so there is no clear correspondence between these concepts.)

I remember extensive discussions (on clcm) about the name "heap". Some
use it to mean the storage place (where new and malloc operate), some
others to mean a data structure - and this is how it is used in the
standard.
Similarly, a "stack" is used to usually mean a *continuous*, growing or
shrinking array of function frames, but it may be a hidden linked list
on the "heap" instead (and I guess that this is how it was implemented
in the C compiler that you mentioned).
 
J

James Kanze

Maciej said:
(e-mail address removed) wrote:
Yes, and that's why it should be preferred to talk about
storage duration (static / dynamic / automatic) instead of
storage "place" (text or global / heap / stack).

To which we might add that we are talking about a guaranteed
minimum storage duration. Since a legal program cannot
determine when the memory is really freed, the implementation
has total freedom.
(Interestingly, temporary objects have automatic storage
duration, but they need not be on the "stack" - this applies
especially to exception objects - so there is no clear
correspondence between these concepts.)

Glad you mentionned that. Althought the standard speaks of
three durations (static, dynamic and automatic), there are a
couple of more which pop up from time to time. Temporary is
one -- the lifetime of a temporary ends at the end of the full
expression in which it occurs (modulo a couple of exceptions),
not at the end of the scope in which it was declared (which is
the case for automatic). And of course, exceptions have a
lifetime of their own.
I remember extensive discussions (on clcm) about the name
"heap". Some use it to mean the storage place (where new and
malloc operate), some others to mean a data structure - and
this is how it is used in the standard.

One doesn't exclude the other. The context is usually
sufficient to know which one is meant.
Similarly, a "stack" is used to usually mean a *continuous*,
growing or shrinking array of function frames, but it may be a
hidden linked list on the "heap" instead (and I guess that
this is how it was implemented in the C compiler that you
mentioned).

Yep. Can't say that it did much for performance, though.
 

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

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top