the different between aaa m1[100] and aaa *p = new [100]

Discussion in 'C++' started by Guest, Mar 14, 2005.

  1. Guest

    Guest Guest

    newbie
    code
    --------------------------
    #include <iostream>
    using namespace std;
    #include <cstring>


    class aaa
    {
    private:
    int age;
    static int num ;
    public:
    aaa();
    ~aaa();
    };
    aaa::aaa()
    {
    ++num;
    cout << " call aaa() one time number =:" << num << endl;
    }

    aaa::~aaa()
    {
    --num;
    cout << " call ~aaa()one time number =:" << num << endl;
    }

    int aaa::num =0;
    int main()
    {
    aaa m1[100];
    aaa *p = new aaa[100];
    ;
    return 0;
    }

    ----------------------------------
    i want to know the deifferent betweent aaa m1[100] and aaa *p = new [100]

    aaa m1[100] will call aaa() 100 times and ~aaa() 100 times
    but aaa *p = new [100] will call aaa() 100 times and dont call ~aaa()

    why??
    Guest, Mar 14, 2005
    #1
    1. Advertising

  2. Guest

    John Carson Guest

    <> wrote in message
    news:d13db8$1ba$
    > newbie
    > code
    > --------------------------
    > #include <iostream>
    > using namespace std;
    > #include <cstring>
    >
    >
    > class aaa
    > {
    > private:
    > int age;
    > static int num ;
    > public:
    > aaa();
    > ~aaa();
    > };
    > aaa::aaa()
    > {
    > ++num;
    > cout << " call aaa() one time number =:" << num << endl;
    > }
    >
    > aaa::~aaa()
    > {
    > --num;
    > cout << " call ~aaa()one time number =:" << num << endl;
    > }
    >
    > int aaa::num =0;
    > int main()
    > {
    > aaa m1[100];
    > aaa *p = new aaa[100];
    > ;
    > return 0;
    > }
    >
    > ----------------------------------
    > i want to know the deifferent betweent aaa m1[100] and aaa *p = new
    > [100]
    >
    > aaa m1[100] will call aaa() 100 times and ~aaa() 100 times
    > but aaa *p = new [100] will call aaa() 100 times and dont call ~aaa()
    >
    > why??


    aaa m1[100] is destroyed when it goes out of scope, which happens when
    main() is exited.

    The 100 instances allocated with new are never destoyed because they never
    go out of scope (variables allocated with new never go out of scope). The p
    variable does go out of scope when main() is exited, so its destructor would
    be called if it had one, but it doesn't have one.

    You have two options:

    1. Call

    delete[] p;

    before main() is exited.

    2. Use a "smart pointer" rather than a regular pointer. A smart pointer is
    an object of a class that functions much the same as a regular pointer but
    does have a destructor. This destructor makes the delete[] p; call for you.


    --
    John Carson
    John Carson, Mar 14, 2005
    #2
    1. Advertising

  3. Guest

    Guest

    [code posted below for brevity]
    > i want to know the deifferent betweent aaa m1[100] and aaa *p = new

    [100]
    >
    > aaa m1[100] will call aaa() 100 times and ~aaa() 100 times
    > but aaa *p = new [100] will call aaa() 100 times and dont call

    ~aaa()
    >
    > why??



    There are a couple differences between declaring an array and a pointer
    to an array.

    The one that most concerns your code is that declaring an array (e.g.
    aaa m1[100];) makes what's called an automatic variable. When main is
    called, space is automagically allocated for m1 and the constructor is
    called for each element. When the main function returns, the destructor
    is automatically called for each element and the space m1 takes up is
    deallocated. Thus you get the 100 messages about the elements in m1
    being deallocated.

    The same is true for the *pointer* p. When main is called, space for p
    is allocated, and when main exits the space is deallocated. (p doesn't
    have a constructor or destructor... keep reading.) The problem comes
    with the fact that p and what p points to -- the array of aaas -- are
    not the same. C++ doesn't care that, when main returns, what p pointed
    to is no longer reachable; it just carries right on. Thus the
    destructor is never called, and the space the array takes up isn't
    deallocated. You have what is called a memory leak, because your
    program has memory that is useless (the technical term is garbage) but
    that it can't deallocate because it doesn't know it's useless. So it's
    wasting it.

    You need to add a 'delete[] p;' line before you return from main. This
    will call the destructor for each element in the array p points to, and
    deallocate the space.


    That's not the only differece though. While pointers and arrays are
    mostly interchangable, they aren't completely. One difference is what
    sizeof() says; sizeof(p) will probably return 4 (depending on the
    platform and compiler you are running), while sizeof(m1) might return
    400, and will at least return something a couple orders of magnitude
    larger than sizeof(p). This is because sizeof(p) knows that p is a
    pointer, but knows nothing about what it points to, while m1 is an
    array of 100 aaas. Each aaa takes up, say, 4 bytes (since is has
    exactly one field, an int, and no virtual functions), so 100 of them
    take up 400 bytes. (Your numbers may vary significantly. I didn't even
    bother to check if these are what comes out on my system. Take them
    with a grain of salt, and try it out yourself to see what they are.
    Just add cout << sizeof(stuff); in there, with 'stuff' replaced by aaa,
    m1, or p.)


    wrote:
    > newbie
    > code
    > --------------------------
    > #include <iostream>
    > using namespace std;
    > #include <cstring>
    >
    >
    > class aaa
    > {
    > private:
    > int age;
    > static int num ;
    > public:
    > aaa();
    > ~aaa();
    > };
    > aaa::aaa()
    > {
    > ++num;
    > cout << " call aaa() one time number =:" << num << endl;
    > }
    >
    > aaa::~aaa()
    > {
    > --num;
    > cout << " call ~aaa()one time number =:" << num << endl;
    > }
    >
    > int aaa::num =0;
    > int main()
    > {
    > aaa m1[100];
    > aaa *p = new aaa[100];
    > ;
    > return 0;
    > }
    >
    > ----------------------------------
    , Mar 14, 2005
    #3
  4. On 14/3/05 7:30 PM, wrote:

    > The one that most concerns your code is that declaring an array (e.g.
    > aaa m1[100];) makes what's called an automatic variable. When main is
    > called, space is automagically allocated for m1 and the constructor is
    > called for each element. When the main function returns, the destructor
    > is automatically called for each element and the space m1 takes up is
    > deallocated. Thus you get the 100 messages about the elements in m1
    > being deallocated.


    In this vein, what are the practical considerations regarding the
    difference between automatic-allocation and new-allocation? That is to
    say, on modern implementations, if the compiler uses a stack for
    automatic variables and the operating system's innate malloc()-like
    function for 'new', what are the limitations regarding size limits,
    having to start on a 4/8/16-byte boundary, etc?
    Richard Cavell, Mar 14, 2005
    #4
  5. Guest

    Guest

    As far as alignment is concerned, I have no clue. It's platform and
    implementation defined, but I can't even give examples; I'm not that
    knowledgable about how alignment works or anything like that. Perhaps
    someone else can fill that in.

    However, typically the heap size is much larger than the stack size. I
    think the default stack size is usually about a meg give or take.
    However, I've run programs that have used a couple hundred megs of heap
    space without changing compiler settings. So your heap is almost
    guranteed to be larger.

    A couple more things of note: new/malloc takes a little time, because
    it has to find an appropriate block of memory. Depending on the
    implementation of malloc/delete, this could be anywhere from usually
    constant time to linear with the number of unallocated blocks. I don't
    know what the glibc version of malloc uses, nor any other common
    implementation. I do have Lion's Commentary on Unix here, and looking
    at the implementation of malloc in it (a really freaking old copy of
    Unix from the PDP11 days), it looks like it uses the first fit
    algorithm. This means that it looks through a list of free blocks
    (areas of memory that aren't allocated) until it finds one that is at
    least large enough to fit the requested size in. In any case, this time
    is usually insignificant, but it's worse than "completely free", which
    is essentially the case with automatic variables. (I'm ignoring
    constructors and any other initialization here.)

    Also, there is a bit of space overhead as well. Remember that you don't
    pass free() the size of the allocated block, so it must keep that
    information somewhere. Often (usually? almost always?) this is kept in
    a header before the block. So if you get back p from malloc, there will
    be a word at *(p-sizeof(int)) that holds the size of that block.

    Also, another point of interest is that usually programs don't release
    memory back to the OS until they exit. For instance, my understanding
    of the working of glibc is that when malloc is called it goes to the OS
    and requests memory from it, gets it, and sets up its own structure in
    it of free blocks, and allocates memory. When that memory gets freed
    from your code, glibc marks that block as unallocated but doesn't do
    anything else. Even if that block was the only allocated space on that
    page, it won't return it to the OS. The thinking is that system calls
    are expensive, so it's better to avoid them if possible. Chances are
    good that if you needed that memory before, you'll need it again.
    Practically, this won't provide a problem because if it isn't used the
    OS will just swap that page out to disk eventually and it'll be ignored
    from then on.

    Please note that all of this information is gleaned from somewhat
    abstract discussions in classes I've had (pretty much my OS course),
    and it's sometimes hard to tell if what we're learning is actually
    things that are being done in practice or if there are better ways, and
    almost all references to implementations in real systems (e.g. glibc)
    are made in passing, so take what I said with a grain of salt.
    , Mar 14, 2005
    #5
  6. Guest

    Guest Guest

    thanks johan & evaned & richard :)

    <> дÈëÏûÏ¢ÐÂÎÅ:d13db8$1ba$...
    > newbie
    > code
    > --------------------------
    > #include <iostream>
    > using namespace std;
    > #include <cstring>
    >
    >
    > class aaa
    > {
    > private:
    > int age;
    > static int num ;
    > public:
    > aaa();
    > ~aaa();
    > };
    > aaa::aaa()
    > {
    > ++num;
    > cout << " call aaa() one time number =:" << num << endl;
    > }
    >
    > aaa::~aaa()
    > {
    > --num;
    > cout << " call ~aaa()one time number =:" << num << endl;
    > }
    >
    > int aaa::num =0;
    > int main()
    > {
    > aaa m1[100];
    > aaa *p = new aaa[100];
    > ;
    > return 0;
    > }
    >
    > ----------------------------------
    > i want to know the deifferent betweent aaa m1[100] and aaa *p = new [100]
    >
    > aaa m1[100] will call aaa() 100 times and ~aaa() 100 times
    > but aaa *p = new [100] will call aaa() 100 times and dont call ~aaa()
    >
    > why??
    >
    >
    >
    Guest, Mar 15, 2005
    #6
    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. Tushar Shelar
    Replies:
    2
    Views:
    9,463
    Tushar Shelar
    Jan 14, 2005
  2. Chris Harris

    OT aaa-webhost.net

    Chris Harris, Dec 11, 2003, in forum: HTML
    Replies:
    8
    Views:
    811
    Tina - AffordableHOST.com
    Dec 12, 2003
  3. fred
    Replies:
    3
    Views:
    253
    Zifud
    Mar 17, 2005
  4. yawnmoth
    Replies:
    4
    Views:
    161
  5. Replies:
    5
    Views:
    856
Loading...

Share This Page