static & dynamic allocation problem

T

toton

Hi,
I have little confusion about static memory allocation & dynamic
allocation for a cluss member.

I have class like
class Bar{
public:
explicit Bar(){
cout<<"bar default"<<endl;
}
explicit Bar(int x){
cout<<"bar int "<<x<<endl;
}
~Bar(){
cout<<"bar dtor"<<endl;
}
};


class Foo{
private:
Bar bar;
public:
explicit Foo(){
cout<<"foo default"<<endl;
}
explicit Foo(int x) : bar(Bar(10)){
cout<<"foo int "<<x<<endl;
}
~Foo(){
//delete bar;
cout<<"foo dtor"<<endl;
}
};

alternative way to write class Foo as,

class Foo{
private:
Bar* bar;
public:
explicit Foo() : bar(new Bar()){
cout<<"foo default"<<endl;
}
explicit Foo(int x) : bar(new Bar(10)){
cout<<"foo int "<<x<<endl;
}
~Foo(){
delete bar;
cout<<"foo dtor"<<endl;
}
};

which Foo class is to be used when? Most of the GUI library (like
wxWindows and Qt) I find the second kind is used (.i.e dynamic
allocation).
Note, in this case the bar objects lifetime is same as Foo's, i.e its
created at Foo constructor & destroyed at Foo's destructor. I know that
if Bar to be initializd any other place that Foo's ctor & destroyed
other than Foo's dtor, the second method is the only way. But if that
is not the case, which one is preferred? any problem wth the virtual
function of Bar for the first implementation?
moreover,
if I initialize,
Foo foo = Foo(4);
for the first sizeof(foo) is 1, while for second it is 4. why is so?
Also how the memory layout is different between first and second case?

thanks in advance

abir
 
W

wei8010

toton 写é“:
Hi,
I have little confusion about static memory allocation & dynamic
allocation for a cluss member.

I have class like
class Bar{
public:
explicit Bar(){
cout<<"bar default"<<endl;
}
explicit Bar(int x){
cout<<"bar int "<<x<<endl;
}
~Bar(){
cout<<"bar dtor"<<endl;
}
};


class Foo{
private:
Bar bar;
public:
explicit Foo(){
cout<<"foo default"<<endl;
}
explicit Foo(int x) : bar(Bar(10)){
cout<<"foo int "<<x<<endl;
}
~Foo(){
//delete bar;
cout<<"foo dtor"<<endl;
}
};

alternative way to write class Foo as,

class Foo{
private:
Bar* bar;
public:
explicit Foo() : bar(new Bar()){
cout<<"foo default"<<endl;
}
explicit Foo(int x) : bar(new Bar(10)){
cout<<"foo int "<<x<<endl;
}
~Foo(){
delete bar;
cout<<"foo dtor"<<endl;
}
};

which Foo class is to be used when? Most of the GUI library (like
wxWindows and Qt) I find the second kind is used (.i.e dynamic
allocation).
Note, in this case the bar objects lifetime is same as Foo's, i.e its
created at Foo constructor & destroyed at Foo's destructor. I know that
if Bar to be initializd any other place that Foo's ctor & destroyed
other than Foo's dtor, the second method is the only way. But if that
is not the case, which one is preferred? any problem wth the virtual
function of Bar for the first implementation?
moreover,
if I initialize,
Foo foo = Foo(4);
for the first sizeof(foo) is 1, while for second it is 4. why is so?
Also how the memory layout is different between first and second case?

thanks in advance

abir

You can try:
class temp
{
public:
temp(void) {}
~temp(void) {}
};

sizeof(temp) = 1;

class temp1
{
public:
temp1(void) {}
~temp1(void) {}
private:
temp t;
};

sizeof(temp1) = 1;

class temp2
{
public:
temp2(void) {}
~temp2(void) {}
private:
temp *t;
};

sizeof(temp2) = 4;
 
S

sun1991

"if I initialize,
Foo foo = Foo(4);
for the first sizeof(foo) is 1, while for second it is 4. why is so? "

The first sizeof(foo) == 1, because for some reason, when c++ compile
meet a class with no member variable, means sizeof(myClass) == 0, it
will fake something into myClass, to make it larger than 0. That is,
You will never get a sizeof(myClass) == 0. I think I have read this
from C++ Primier.

The next sizeof(foo) is actually the size of Bar*.
 
T

toton

toton 写é“:


You can try:
class temp
{
public:
temp(void) {}
~temp(void) {}
};

sizeof(temp) = 1;

class temp1
{
public:
temp1(void) {}
~temp1(void) {}
private:
temp t;
};

sizeof(temp1) = 1;

class temp2
{
public:
temp2(void) {}
~temp2(void) {}
private:
temp *t;
};

sizeof(temp2) = 4;
I understand why sizeof(temp2) is 4. 4 byte is the pointer size for 32
bit platform. What I don't understand is why sizeof(temp1) is 1. It
should be zero! Is it just to follow the spec that sizeof(char) is
always 1 and minimum size for anything?

More than that, my question is when to use which style, ie. when to use
Bar* bar, and when Bar bar as a class member variable. and what are the
consequences for virtual function and memory allocation.

thanks
 
I

Isold.Wang

See this book said:
I understand why sizeof(temp2) is 4. 4 byte is the pointer size for 32
bit platform. What I don't understand is why sizeof(temp1) is 1. It
should be zero! Is it just to follow the spec that sizeof(char) is
always 1 and minimum size for anything?

More than that, my question is when to use which style, ie. when to use
Bar* bar, and when Bar bar as a class member variable. and what are the
consequences for virtual function and memory allocation.

thanks
 
C

Clark S. Cox III

I understand why sizeof(temp2) is 4. 4 byte is the pointer size for 32
bit platform. What I don't understand is why sizeof(temp1) is 1. It
should be zero! Is it just to follow the spec that sizeof(char) is
always 1 and minimum size for anything?


Imagine you had an array of temp1:

temp1 array[10];

If sizeof(temp1) were 0, then many things would break down. For
instance, all elements of the array would have the same exact address.
Since every object of the same type must have a unique address, this
situation must be prevented; hence, every complete type must have a
size of at least 1.
 
M

mlimber

toton said:
I have little confusion about static memory allocation & dynamic
allocation for a cluss member.

I have class like
class Bar{
public:
explicit Bar(){
cout<<"bar default"<<endl;
}
explicit Bar(int x){
cout<<"bar int "<<x<<endl;
}
~Bar(){
cout<<"bar dtor"<<endl;
}
};


class Foo{
private:
Bar bar;
public:
explicit Foo(){
cout<<"foo default"<<endl;
}
explicit Foo(int x) : bar(Bar(10)){
cout<<"foo int "<<x<<endl;
}
~Foo(){
//delete bar;
cout<<"foo dtor"<<endl;
}
};

alternative way to write class Foo as,

class Foo{
private:
Bar* bar;
public:
explicit Foo() : bar(new Bar()){
cout<<"foo default"<<endl;
}
explicit Foo(int x) : bar(new Bar(10)){
cout<<"foo int "<<x<<endl;
}
~Foo(){
delete bar;
cout<<"foo dtor"<<endl;
}
};

which Foo class is to be used when? Most of the GUI library (like
wxWindows and Qt) I find the second kind is used (.i.e dynamic
allocation).
Note, in this case the bar objects lifetime is same as Foo's, i.e its
created at Foo constructor & destroyed at Foo's destructor. I know that
if Bar to be initializd any other place that Foo's ctor & destroyed
other than Foo's dtor, the second method is the only way. But if that
is not the case, which one is preferred?

Either could be useful depending on the situation, though in the second
case I'd suggest using a smart pointer/container that gives exception
safety (cf.
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.2) and
automatic cleanup instead of explicit news and deletes (cf.
http://www.parashift.com/c++-faq-lite/containers.html#faq-34.1).

In general, you should use explicit dynamic allocation only when you
have to (e.g., with polymorphic objects, with objects intialized
outside the constructor, etc.), but sometimes using a pointer can
reduce compile-time dependencies and speed up build times. See
http://www.gotw.ca/publications/mill04.htm.
any problem wth the virtual
function of Bar for the first implementation?

There is no virtual function in your Bar class above, but there would
be no inherent problem if there were (but cf.
http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7)
unless you were expecting to use Bar as a polymorphic object. For that
you'd need a pointer or reference.
moreover,
if I initialize,
Foo foo = Foo(4);
for the first sizeof(foo) is 1, while for second it is 4. why is so?

This has been covered in the other responses.
Also how the memory layout is different between first and second case?

The compiler has some flexibility with memory layout and classes with
private data (it could add padding or move things around a bit, and if
you add a virtual function as it seems you meant to do, other things
can change), so it's impossible to say in general. Thus, you should not
depend on the low-level layout of your classes in the usual case.
However, we can of course say that the first case has an instance of
class Bar as part of its memory footprint, whereas the second only has
a pointer to a Bar as part of its footprint.

Cheers! --M
 
T

toton

mlimber said:
Either could be useful depending on the situation, though in the second
case I'd suggest using a smart pointer/container that gives exception
safety (cf.
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.2) and
automatic cleanup instead of explicit news and deletes (cf.
http://www.parashift.com/c++-faq-lite/containers.html#faq-34.1).

In general, you should use explicit dynamic allocation only when you
have to (e.g., with polymorphic objects, with objects intialized
outside the constructor, etc.), but sometimes using a pointer can
reduce compile-time dependencies and speed up build times. See
http://www.gotw.ca/publications/mill04.htm.


There is no virtual function in your Bar class above, but there would
be no inherent problem if there were (but cf.
http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7)
unless you were expecting to use Bar as a polymorphic object. For that
you'd need a pointer or reference.


This has been covered in the other responses.


The compiler has some flexibility with memory layout and classes with
private data (it could add padding or move things around a bit, and if
you add a virtual function as it seems you meant to do, other things
can change), so it's impossible to say in general. Thus, you should not
depend on the low-level layout of your classes in the usual case.
However, we can of course say that the first case has an instance of
class Bar as part of its memory footprint, whereas the second only has
a pointer to a Bar as part of its footprint.
Thanks for the reply.
Thus can I safely assume that using heap allocation (may be with
auto_ptr ) will not have n any performance problem?
In fact I am using container classes for arrays, but again there are
two types of allocation can be done.
like vector<MyClass> and vector<MyClass*>
I have flexibility and easeness for second type ( I never forget to
delete memory, also I use all the boost pointers whichone suitable :) )
Only thing, most of the time people say stack based alocation is much
much faster than heap mased one. I am not sure how much true it is, but
like heap based as it offers flexibility, as I can initialize the
object when I need and the way I want.
But what I feel, for container class stack based initialization causes
all of the classes to reside nearby memory, which is not so for heap
based classes.
And syntactically one needs one more line of code if wants to use
overloaded operators for heap based classes (minor problem to me).
Something I have noticed like a few books only gives an good intro to
heap based allocation, people rarely put pointer to class inside a STL
container, and I rarely get a code which initialized a template class
on heap.
On the otherhand, nearly all of the GUI frameworks (MFC is mixed) ,
most of networking framework, graphics framework etc use heap based
allocation always.
Even I came across some GUI framework like Ultimate++ which uses stack
memory for the GUI components, while most other (like Qt VCF wxWidgets
VCL etc) uses heap allocation. even some of the framework reserve
struct for stack bases & class for heap based allocation (artificially,
I know there is no restriction from language).
I am basically interested in some sort of performance comparison for
it. And in turn some sort of guideline, when to use which one.
 
P

peter koch

toton skrev:
mlimber said:
toton said:
I have little confusion about static memory allocation & dynamic
allocation for a cluss member.

I have class like [snip example with member as pointer or as variable]
which Foo class is to be used when? Most of the GUI library (like
wxWindows and Qt) I find the second kind is used (.i.e dynamic
allocation).
Note, in this case the bar objects lifetime is same as Foo's, i.e its
created at Foo constructor & destroyed at Foo's destructor. I know that
if Bar to be initializd any other place that Foo's ctor & destroyed
other than Foo's dtor, the second method is the only way. But if that
is not the case, which one is preferred?

Either could be useful depending on the situation, though in the second
case I'd suggest using a smart pointer/container that gives exception
safety (cf.
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.2) and
automatic cleanup instead of explicit news and deletes (cf.
http://www.parashift.com/c++-faq-lite/containers.html#faq-34.1).

In general, you should use explicit dynamic allocation only when you
have to (e.g., with polymorphic objects, with objects intialized
outside the constructor, etc.), but sometimes using a pointer can
reduce compile-time dependencies and speed up build times. See
http://www.gotw.ca/publications/mill04.htm.
[snip]
Thanks for the reply.
Thus can I safely assume that using heap allocation (may be with
auto_ptr ) will not have n any performance problem?

No you can not. Follow mlimbers advice and avoid pointers unless you
have to. Using new and delete will invariably incur a cost in memory as
well as cpu-time. If it turns up to be a performance problem, i cant
tell - it depends on lots of things.
But more importantly, using pointers require far more code and is not
completely trivial to implement (Your original code was buggy).
In fact I am using container classes for arrays, but again there are
two types of allocation can be done.
like vector<MyClass> and vector<MyClass*>
I have flexibility and easeness for second type ( I never forget to
delete memory, also I use all the boost pointers whichone suitable :) )
Again, use the simplest method available and refactor if it turns out
to be insufficient.
Only thing, most of the time people say stack based alocation is much
much faster than heap mased one. I am not sure how much true it is

It is accurate. A stack allocation is practically a free lunch in the
environments I work in (Windows/Unix). This is not true for a heap
allocation.
, but
like heap based as it offers flexibility, as I can initialize the
object when I need and the way I want.
[snip]

/Peter
 
T

toton

peter said:
toton skrev:
mlimber said:
toton wrote:
I have little confusion about static memory allocation & dynamic
allocation for a cluss member.

I have class like [snip example with member as pointer or as variable]
which Foo class is to be used when? Most of the GUI library (like
wxWindows and Qt) I find the second kind is used (.i.e dynamic
allocation).
Note, in this case the bar objects lifetime is same as Foo's, i.e its
created at Foo constructor & destroyed at Foo's destructor. I know that
if Bar to be initializd any other place that Foo's ctor & destroyed
other than Foo's dtor, the second method is the only way. But if that
is not the case, which one is preferred?

Either could be useful depending on the situation, though in the second
case I'd suggest using a smart pointer/container that gives exception
safety (cf.
http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.2) and
automatic cleanup instead of explicit news and deletes (cf.
http://www.parashift.com/c++-faq-lite/containers.html#faq-34.1).

In general, you should use explicit dynamic allocation only when you
have to (e.g., with polymorphic objects, with objects intialized
outside the constructor, etc.), but sometimes using a pointer can
reduce compile-time dependencies and speed up build times. See
http://www.gotw.ca/publications/mill04.htm.
[snip]
Thanks for the reply.
Thus can I safely assume that using heap allocation (may be with
auto_ptr ) will not have n any performance problem?

No you can not. Follow mlimbers advice and avoid pointers unless you
have to. Using new and delete will invariably incur a cost in memory as
well as cpu-time. If it turns up to be a performance problem, i cant
tell - it depends on lots of things.
But more importantly, using pointers require far more code and is not
completely trivial to implement (Your original code was buggy).
In fact I am using container classes for arrays, but again there are
two types of allocation can be done.
like vector<MyClass> and vector<MyClass*>
I have flexibility and easeness for second type ( I never forget to
delete memory, also I use all the boost pointers whichone suitable :) )
Again, use the simplest method available and refactor if it turns out
to be insufficient.
Only thing, most of the time people say stack based alocation is much
much faster than heap mased one. I am not sure how much true it is

It is accurate. A stack allocation is practically a free lunch in the
environments I work in (Windows/Unix). This is not true for a heap
allocation.
, but
like heap based as it offers flexibility, as I can initialize the
object when I need and the way I want.
[snip]
My reason of asking the question is, no book refers dynamic memory
allocation in detail, and nearly no framework (like MFC Qt GTKmm VCF
VCL wxWindows and many others) uses stack based allocation . Don't you
see a little difference between the textbook examples and commercial
implementation? Most of them dont use stl containers (use their own).
But the modern one like VCF uses, but they store pointer to the class
inside the container, rather than the class itself. Moreover the
standard they follow like, the class which need to acquire system
resource like gui, filesystem , network etc need to be initialized in
heap, on the otherhand classes like Point, Dimension, Rect etc
initialize in stack (many of them use a struct syntax for them).
Many of them use reference count rather than explicit delete.
Thus when I program using such a framework, the concept is not matching
properly with same coding guideline. Moreover I am seeing no escape
fromusing pointer to initialize things, and passing the classes as
reference.
Infact how a few big class can be allocated in a vector whitout
pointer?
If I say vector<Component> wont is occupy memory of a few Component
even though no component is added? None of the existing library do it,
they do vector<Compoent*>.
Problems comes like, how to do static memory allocation for a Image,
image data need to be a pointer, and allocated dynamically. even the
frameworks write Image* image = new Image(filename) , rather than Image
image = Image(filename) most of the time .

The whole things look little strange to me, one c++ std thing, who
thinks differently, and other the commercial/ oss frameworks.
Infact most of the framework (not only GUI, the framework contains much
more) ,dont use std iostream, very less use even std string, they dont
go for template, they implement their own RTTI, very less of them use
STL containers, almost none use boost serialization, etc.
I am not sure why they are pole apart. I hadn't used C++ for no big
application, except the standard console based little programs. But I
used Java for some time for large enough project, were everything
looked consistent.
Now back to C++ for one of my personal project (will be GPLed!!) , I
decided to use VCF for GUI, networking, filesystem support etc, and I
find simply they are different than book examples. In fact they look
'Javaish ' to me rather than C++ish :) They are simple, they are subset
of C++, and simply different.
So when I use one of the framework (VCF) in my application, and try to
use the stack based alocation & template etc, the whole thing becomes
chaotic.
Can anyone say about the experience with any of the framework, and if
any problem they faced with the standard C++ type of implementation? Or
any book dealt with this?

thanks a lot.
 
M

mlimber

toton said:
peter said:
toton skrev:
Only thing, most of the time people say stack based alocation is much
much faster than heap mased one. I am not sure how much true it is

It is accurate. A stack allocation is practically a free lunch in the
environments I work in (Windows/Unix). This is not true for a heap
allocation.
, but
like heap based as it offers flexibility, as I can initialize the
object when I need and the way I want.
[snip]

My reason of asking the question is, no book refers dynamic memory
allocation in detail,

Huh? What sort of detail are you looking for that is not found in, say,
Stroustrup's _The C++ Programming Language_ 3rd ed. or Josuttis' _The
Standard Library_?
and nearly no framework (like MFC Qt GTKmm VCF
VCL wxWindows and many others) uses stack based allocation .

True, but many of them have constraints that may force their hand in
that department (e.g., supporting multiple platforms with polymorphism,
supporting legacy code that is not written according to current best
practice, supporting C and C++, etc.).
Don't you
see a little difference between the textbook examples and commercial
implementation? Most of them dont use stl containers (use their own).

Some of them were written before the STL was finalized as part of the
language, and rather than rewrite everything, they kept their in-house
containers. The STL was added to obviate the need for everyone to write
their own containers for every project, i.e. to standardize practice
across the industry.
But the modern one like VCF uses [STL], but they store pointer to the class
inside the container, rather than the class itself. Moreover the
standard they follow like, the class which need to acquire system
resource like gui, filesystem , network etc need to be initialized in
heap, on the otherhand classes like Point, Dimension, Rect etc
initialize in stack (many of them use a struct syntax for them).
Many of them use reference count rather than explicit delete.
Thus when I program using such a framework, the concept is not matching
properly with same coding guideline. Moreover I am seeing no escape
fromusing pointer to initialize things, and passing the classes as
reference.

Like I said, avoid pointers when you can. But sometimes you need them,
and one of those times is when the OS or library requires a pointer.
Infact how a few big class can be allocated in a vector whitout
pointer?
If I say vector<Component> wont is occupy memory of a few Component
even though no component is added?

No. A declaration such as

vector<BigClass> v;

doesn't allocate space for anything (except the internal members of
std::vector, which are usually a few pointers). You might be thinking
of the way vector grows by doubling its size, but that effect can be
mitigated by using reserve() or by stripping excess capacity at
appropriate points.
None of the existing library do it,
they do vector<Compoent*>.
Problems comes like, how to do static memory allocation for a Image,
image data need to be a pointer, and allocated dynamically. even the
frameworks write Image* image = new Image(filename) , rather than Image
image = Image(filename) most of the time .

I would prefer

Image image( filename );
The whole things look little strange to me, one c++ std thing, who
thinks differently, and other the commercial/ oss frameworks.

This is the most important line in this post: Different groups have
different goals, different tools, and different compentancies. You'd
have to ask each vendor why they chose to use or not use standard
containers (see above for some of my guesses as to their answers), but
I'd say you should use the best practices for software development that
you can and convert to lesser styles when you must. For instance, in my
current project, I have to interface with a C-style library for array
processing, but all my data is contained in std::vectors. So I must
convert when I make that library call:

void CallSomeLib( int*, unsigned );
vector<int> v;
// ... fill v here ...
CallSomeLib( &v[0], v.size() );
Infact most of the framework (not only GUI, the framework contains much
more) ,dont use std iostream, very less use even std string, they dont
go for template, they implement their own RTTI, very less of them use
STL containers, almost none use boost serialization, etc.
I am not sure why they are pole apart.

See above for why this is.
I hadn't used C++ for no big
application, except the standard console based little programs. But I
used Java for some time for large enough project, were everything
looked consistent.
Now back to C++ for one of my personal project (will be GPLed!!) , I
decided to use VCF for GUI, networking, filesystem support etc, and I
find simply they are different than book examples. In fact they look
'Javaish ' to me rather than C++ish :) They are simple, they are subset
of C++, and simply different.
So when I use one of the framework (VCF) in my application, and try to
use the stack based alocation & template etc, the whole thing becomes
chaotic.

C++ is a general purpose language that runs natively on many platforms,
and unlike Java, C++ does not have standard GUI support. Indeed, the
Creator says of the future of GUI support: "Sadly, I cannot offer hope
for the most frequently wished for new standard library: a standard GUI
library. A GUI library is simply too large a task for the volunteers of
the C++ standards committee to handle and too difficult a task given
the many (non-standard but huge, useful, and supported) GUI libraries
available. Please notice that even though they are not standard, the
major C++ GUIs have more users than most programming languages and are
often better supported." (http://www.artima.com/cppsource/cpp0x2.html)
Can anyone say about the experience with any of the framework, and if
any problem they faced with the standard C++ type of implementation? Or
any book dealt with this?

Your question is too broad, but you can search the web for discussions
about using std::string with MFC's CString, for instance. There are
plenty of problems interfacing the standard library with third-party
libraries of all sorts, but those discussions are often off-topic here
(see http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.9).

I have used standard C++ with various third-party libraries and
interfaces (MFC, COM, C-style number crunching libraries, OS system
calls, etc.), and I design the system to keep my "business logic,"
which is written in standard C++ according to current best practices,
separate from the from all third-party library code. Sometimes, this
means that I wrap the third-party calls in standard C++, e.g., by
creating an abstract factory that returns a pointer to an object that
implements the interface for that particular platform (for instance, I
did this for synchronization primitives for multithreading on different
platforms). Sometimes it means that I keep the two as separate as
possible and convert between my interface and theirs when crossing the
boundary (cf. std::string vs. CString and the CallSomeLib example
above).

Cheers! --M
 

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,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top