C++ Objects, Stack or Heap? [Noob question]

Discussion in 'C++' started by Olumide, Sep 18, 2004.

  1. Olumide

    Olumide Guest

    In the following C++ class,

    MyClass{
    // Members
    }


    From which I create two objects (using the default constructor),
    (1) MyClass *object1 = new MyClass(); // Stack
    (2) MyClass object2 = MyClass(); // Stack or Heap?

    Are both objects (1) and (2) created on the heap or is (1) only? I suspect
    this is the case, but I'm not 100% sure because I have not read this
    anywhere.

    Thanks,

    - Olumide
    Olumide, Sep 18, 2004
    #1
    1. Advertising

  2. Olumide wrote:

    > In the following C++ class,
    >
    > class MyClass{
    > // Members
    > };
    >
    >
    > From which I create two objects (using the default constructor),
    > (1) MyClass *pobject1 = new MyClass(); // Free Storage
    > (2) MyClass object2 = MyClass(); // Automatic Storage
    >
    > Are both objects (1) and (2) created on the heap or is (1) only?
    > I suspect this is the case,
    > but I'm not 100% sure because I have not read this anywhere.


    You are wrong either way.
    Storage is allocated from *free storage* for the object
    to which pobject1 points in the first case and
    storage is allocated from *automatic storage* for object2
    in the second case.

    In the *typical implementation*,
    the *program stack* is used for automatic storage and
    a *free list* is used to manage free storage.
    The whimsical term *heap* is a pun used by IBM programmers
    to contrast their implementation of a free list
    with a stack data structure.
    E. Robert Tisdale, Sep 19, 2004
    #2
    1. Advertising

  3. Olumide

    Baalbek Guest

    Olumide wrote:
    > In the following C++ class,
    >
    > MyClass{
    > // Members
    > }
    >
    >
    > From which I create two objects (using the default constructor),
    > (1) MyClass *object1 = new MyClass(); // Stack
    > (2) MyClass object2 = MyClass(); // Stack or Heap?
    >
    > Are both objects (1) and (2) created on the heap or is (1) only? I suspect
    > this is the case, but I'm not 100% sure because I have not read this
    > anywhere.
    >
    > Thanks,
    >
    > - Olumide
    >


    The MyClass *object1 pointer is created on the stack, but the object it
    points to is created on the heap. That is, the pointer is automatically
    destroyed, but the object on the heap is not (necessitating "delete
    object1", that is deleting the object on the heap object1 points to).

    MyClass object2 is an object created on the stack.

    So, creating many (large) objects like object2 can lead to stack-overflow.

    Baalbek
    Baalbek, Sep 19, 2004
    #3
  4. Olumide

    aaaaa Guest

    You area Java guy huh? :p

    Better that you read something like "Thinking in C++" freely available
    on the web. Your ideas about C++ are somewhat confused (by Java).


    > From which I create two objects (using the default constructor),
    > (1) MyClass *object1 = new MyClass(); // Stack


    ^^^^ stack ^^^^ heap

    ^^^ an object

    ^^^ a pointer,not an object

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    remember to do
    delete object1;
    at a certain point, below, when you don't need it anymore. You have no
    garbage collector in C++!!


    > (2) MyClass object2 = MyClass(); // Stack or Heap?


    ^^^^ stack ^^^^ stack
    ^^^ an object
    ^^^ an object (temporary and
    immediately destroyed)
    ^^^ value of object copied from the temporary on the right

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ DON'T DO THIS (2) STUFF IN C++!!
    do simply:
    MyClass object2(....possible params...);
    aaaaa, Sep 19, 2004
    #4
  5. Olumide

    JKop Guest

    > DON'T DO THIS (2) STUFF IN C++!!


    I always do it with POD types.

    For instance, Microgay, opps I mean Microsoft, have the
    likes of the following in their documentation:

    FIND_DATA find_data;
    memset(&find_data,sizeof(FIND_DATA),0);


    While I, being a proficient C++ programmer, do:

    FIND_DATA find_data = FIND_DATA();


    Benefits of my method:

    A) You don't mess with padding, which I believe is taboo...

    B) If you have any pointers in there, then they'll get the
    null pointer value, as opposed to simply "all bits zero".

    C) YOu don't have the overhead of calling memset.


    2 of my benefits are moot with Windows because:

    A) You're allowed mess with padding
    B) The null pointer value *is* "all bits zero"

    But still, you don't have to call memset.

    After that, the main advantage is that my code is fully
    portable!

    -JKop
    JKop, Sep 19, 2004
    #5

  6. >
    > While I, being a proficient C++ programmer, do:
    >
    > FIND_DATA find_data = FIND_DATA();
    >
    >



    Its a bit early on a Sunday for me to remember the distinction between
    default initialization and the other sort, but the line of code
    above, isn't it the same as

    FIND_DATA find_data;

    or for that matter....
    FIND_DATA find_data( FIND_DATA() );

    The original requires that you have a assignment operator, whereas
    the second form does not. ( Well, I suppose the last one requires you
    have a copy constructor).

    yawn..
    Dave Townsend, Sep 19, 2004
    #6
  7. Olumide

    JKop Guest

    Dave Townsend posted:

    >
    > >
    >> While I, being a proficient C++ programmer, do:
    >>
    >> FIND_DATA find_data = FIND_DATA();
    >>
    >>

    >
    >
    > Its a bit early on a Sunday for me to remember the distinction between
    > default initialization and the other sort, but the line of code
    > above, isn't it the same as
    >
    > FIND_DATA find_data;
    >
    > or for that matter....
    > FIND_DATA find_data( FIND_DATA() );


    BULLSHIT.

    Okay here goes:

    int i;
    char* p_blah;

    Right now those two variables contain white noise, no particular value. A
    piece of memory was just allocated, it wasn't zeroed.

    struct Poo
    {
    int i;
    char* p_blah;
    };

    Poo black;


    Right now, "black.i" and "black.p_blah" contain white noise.

    Here's how to get things set to their default value:

    int i = int();
    char* p_blah = char*();

    Poo black = Poo();


    Note that the above are all POD types.

    When you're dealing with classes, then:

    std::string k;
    std::string k = string();

    are identical, because the Constructor takes over.


    > The original requires that you have a assignment operator, whereas
    > the second form does not. ( Well, I suppose the last one requires you
    > have a copy constructor).


    As regards assignment operator... BULLSHIT, it's not involved at all.

    std::string k = std::string();

    is identical in every way to:

    std::string k( std::string() );

    As regards Copy Constructor, you're correct. If there's no copy contructor
    defined, then the miranda one takes over.
    If there's a copy constructor defined but it's private, then it doesn't
    work.

    So if you do:

    FIND_DATA find_data;

    Then it contains white noise. While if you do:

    FIND_DATA find_data = FIND_DATA();

    Then everything gets their default values, which for ints is 0, and for
    pointers is the NULL pointer value, which may or may not be "all bits zero".


    -JKop
    JKop, Sep 19, 2004
    #7
  8. Olumide

    mbcf78 Guest

    JKop wrote:

    > While I, being a proficient C++ programmer, do:
    >
    > FIND_DATA find_data = FIND_DATA();


    Doesn't this have a *very bad* performance overhead?

    You are first creating a temporary FIND_DATA type (the one on the right
    side of = sign), so a space is created on the stack for it and then its
    memory is zeroed.

    Then you create a space also for the one on the left side and you call
    the (implicit) copy constructor to copy the one on the right to the one
    on the left, member by member (so there are N reads and N writes which
    are just to copy zeroes...)

    Seems very bad to me, compared to the Microsoft proposed way of just
    writing zeroes once.

    Or you can guarantee to me that some of these steps are optimized away
    because of some specific known optimizations I am not aware of? Please tell.
    mbcf78, Sep 21, 2004
    #8
  9. JKop wrote:

    > Okay here goes:
    >
    > int i;
    > char* p_blah;
    >
    > Right now those two variables contain white noise, no particular value. A
    > piece of memory was just allocated, it wasn't zeroed.
    >
    > struct Poo
    > {
    > int i;
    > char* p_blah;
    > };
    >
    > Poo black;
    >
    >
    > Right now, "black.i" and "black.p_blah" contain white noise.



    :) Unless they are declared global, static in a function, or in a
    namespace.




    > Here's how to get things set to their default value:



    As it is written in TC++PL3:

    "void f(double d)
    {
    int j = int() ; // default int value
    complex z = complex() ; // default complex value
    // ...
    }

    The value of an explicit use of the constructor for a built-in
    type is 0 converted to that type (§4.9.5).

    Thus, int() is another way of writing 0. For a user-defined
    type T, T() is defined by the default constructor (§10.4.2), if any.

    The use of the constructor notation for built-in types is particularly
    important when writing templates. Then, the programmer does not know
    whether a template parameter will refer to a built-in type or a
    user-defined type (§16.3.4, §17.4.1.2)."


    So basically, its importance for built in types is when they are used
    with templates.




    > int i = int();
    > char* p_blah = char*();



    What about this:


    int i=0;

    char *p=0;


    > Poo black = Poo();



    This one is using the provided constructor (in this case the built in),
    which does not necessarily initialise to 0.

    For example:


    struct Poo
    {
    int i;
    char *p;

    Poo() { i=1, p=new char[10]; }
    };


    int main()
    {
    Poo b;
    }



    --
    Ioannis Vranos

    http://www23.brinkster.com/noicys
    Ioannis Vranos, Sep 21, 2004
    #9
  10. mbcf78 wrote:

    > JKop wrote:
    >
    >> While I, being a proficient C++ programmer, do:
    >>
    >> FIND_DATA find_data = FIND_DATA();

    >
    > Doesn't this have a *very bad* performance overhead?


    No.

    > You are first creating a temporary FIND_DATA type
    > (the one on the right side of = sign),
    > so a space is created on the stack for it and then its memory is zeroed.
    >
    > Then you create a space also for the one on the left side and you call
    > the (implicit) copy constructor to copy the one on the right to the one
    > on the left, member by member


    No.
    A good optimizing C++ compiler will call the default constructor
    to initialize find_data directly. The copy constructor will be elided.

    > (so there are N reads and N writes which are just to copy zeroes...)
    >
    > Seems very bad to me
    > compared to the Microsoft proposed way of just writing zeroes once.
    >
    > Or you can guarantee to me that some of these steps are optimized away
    > because of some specific known optimizations I am not aware of?


    This optimization is well known.
    I used Google

    http://www.google.com/
    to search for

    +"copy constructor" +"elided" +"C++"

    and found lots of stuff.

    > Please tell.
    E. Robert Tisdale, Sep 21, 2004
    #10
  11. Olumide

    Old Wolf Guest

    "Dave Townsend" <> wrote:
    > >
    > > FIND_DATA find_data = FIND_DATA();

    >
    > Its a bit early on a Sunday for me to remember the distinction between
    > default initialization and the other sort, but the line of code
    > above, isn't it the same as
    >
    > FIND_DATA find_data;
    >
    > or for that matter....
    > FIND_DATA find_data( FIND_DATA() );


    This was changed in C++03.
    Original:
    An object whose initializer is an empty set of parentheses,
    i.e., (), shall be default-initialized
    Replacement:
    An object whose initializer is an empty set of parentheses,
    i.e., (), shall be value-initialized

    The relevant parts of the definition of "value-initialized" is:
    if T is a non-union class type without a user-declared
    constructor, then every non-static data member and base-class
    component of T is value-initialized;

    otherwise, the object is zero-initialized.

    See http://www.acceleratedcpp.com/authors/koenig/c std/revisions.pdf
    for more info.


    > The original requires that you have a assignment operator, whereas
    > the second form does not. ( Well, I suppose the last one requires you
    > have a copy constructor).


    Initialization has never required an assignment operator.
    The syntax:
    T x = EXPRESSION;
    creates x using T::T(T [const] &), if EXPRESSION has type 'T'.

    If not, then the compiler treats it as:
    T x = T(EXPRESSION)
    which was covered by the first case.
    Old Wolf, Sep 21, 2004
    #11
  12. Olumide

    JKop Guest

    >> Poo black = Poo();
    >
    >
    > This one is using the provided constructor (in this case

    the built in),
    > which does not necessarily initialise to 0.


    Incorrect.

    My definition of Poo is a POD. When you do:

    Poo black = Poo();

    with a POD, all member variables get their default value.

    >
    > For example:
    >
    >
    > struct Poo
    > {
    > int i;
    > char *p;
    >
    > Poo() { i=1, p=new char[10]; }
    > };


    With *your* definition of Poo, yes you are correct, in
    that:

    Poo black;

    and

    Poo black = Poo();

    Are equal, they just call the default constructor,
    *without* giving all the member variables their default
    value (unless ofcourse the aforementioned constructor does
    so in its initialization list).


    -JKop
    JKop, Sep 21, 2004
    #12
  13. Olumide

    JKop Guest

    > No.
    > A good optimizing C++ compiler will call the default constructor
    > to initialize find_data directly. The copy constructor will be elided.



    I don't know why people keep labeling a compiler that does this as a "good
    optimizing" compiler.

    This is the BOG BOG BOG standard. If your compiler doesn't do this, then
    it's a pesimizing compiler.


    -JKop
    JKop, Sep 21, 2004
    #13
  14. JKop wrote:

    > Incorrect.
    >
    > My definition of Poo is a POD. When you do:
    >
    > Poo black = Poo();
    >
    > with a POD, all member variables get their default value.



    I checked the standard and can't reach a conclusion. However in TC++PL
    only this is mentioned:


    "The value of an explicit use of the constructor for a built-in
    type is 0 converted to that type (§4.9.5). Thus, int() is another way of
    writing 0. For a user-defined type T, T() is defined by the default
    constructor (§10.4.2), if any."


    Perhaps someone may help?



    --
    Ioannis Vranos

    http://www23.brinkster.com/noicys
    Ioannis Vranos, Sep 21, 2004
    #14
  15. Olumide

    JKop Guest

    Ioannis Vranos posted:

    > JKop wrote:
    >
    >> Incorrect.
    >>
    >> My definition of Poo is a POD. When you do:
    >>
    >> Poo black = Poo();
    >>
    >> with a POD, all member variables get their default

    value.
    >
    >
    > I checked the standard and can't reach a conclusion.

    However in TC++PL
    > only this is mentioned:
    >
    >
    > "The value of an explicit use of the constructor for a

    built-in
    > type is 0 converted to that type (§4.9.5). Thus, int() is

    another way of
    > writing 0. For a user-defined type T, T() is defined by

    the default
    > constructor (§10.4.2), if any."
    >
    >
    > Perhaps someone may help?


    And this also holds true for structures:

    struct Blah
    {
    int k;
    char* p;
    };

    int main()
    {
    Blah cheese = Blah();

    //The get their default values
    }


    -JKop
    JKop, Sep 21, 2004
    #15
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. joe

    stack and heap question

    joe, Aug 4, 2004, in forum: Java
    Replies:
    3
    Views:
    424
    Michael Borgwardt
    Aug 5, 2004
  2. Dan Elliott

    stack vs. heap. a loaded question.

    Dan Elliott, Nov 17, 2004, in forum: C++
    Replies:
    11
    Views:
    3,608
    Daniel L Elliott
    Nov 19, 2004
  3. Michal Slocinski

    Heap dump file size vs heap size

    Michal Slocinski, Mar 25, 2008, in forum: Java
    Replies:
    1
    Views:
    722
    GArlington
    Mar 25, 2008
  4. viki
    Replies:
    6
    Views:
    556
    Erik Wikström
    Jun 28, 2008
  5. Raymond Schanks
    Replies:
    0
    Views:
    504
    Raymond Schanks
    Apr 11, 2010
Loading...

Share This Page