basic question for pointer

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • kathy

    #1

    basic question for pointer

    If I have 2D array like:

    int **p;

    p = new int*[10];

    for(int i=0;i<10;i++)
    {
    p[i] = new int[10];
    }

    To delete the p, should I use:

    for(int i=0;i<10;i++)
    {
    delete p[i];
    }
    delete p;

    or just:

    delete p;

  • Neil Cerutti

    #2
    Re: basic question for pointer

    On 2006-02-22, kathy <yqin_99@yahoo. com> wrote:[color=blue]
    > If I have 2D array like:
    >
    > int **p;
    >
    > p = new int*[10];
    >
    > for(int i=0;i<10;i++)
    > {
    > p[i] = new int[10];
    > }
    >
    > To delete the p, should I use:
    >
    > for(int i=0;i<10;i++)
    > {
    > delete p[i];
    > }
    > delete p;
    >
    > or just:
    >
    > delete p;[/color]

    The answer is C, none of the above.

    delete[] p;

    --
    Neil Cerutti
    Scouts are saving aluminum cans, bottles, and other items to be
    recycled. Proceeds will be used to cripple children. --Church
    Bulletin Blooper

    Comment

    • Gavin Deane

      #3
      Re: basic question for pointer


      kathy wrote:[color=blue]
      > If I have 2D array like:
      >
      > int **p;
      >
      > p = new int*[10];
      >
      > for(int i=0;i<10;i++)
      > {
      > p[i] = new int[10];
      > }[/color]

      Every new must have a matching delete.
      Every new [] must have a matching delete [].

      The two are not the same thing. Mixing new with delete [] or mixing new
      [] with delete (as you do) is undefined.
      [color=blue]
      > To delete the p, should I use:
      >
      > for(int i=0;i<10;i++)
      > {
      > delete p[i];[/color]

      No, it should be delete [] p[i]; because p[i] points to a dynamically
      allocated *array*. The memory pointed to by p[i] was allocated with new
      [], not with new.
      [color=blue]
      > }
      > delete p;[/color]

      Similarly, this should be delete [] p;
      [color=blue]
      > or just:
      >
      > delete p;[/color]

      No, definitely not that.

      That's all well and good for learning how to manage dynamically
      allocated 2D arrays, but in real code, if you prefer
      std::vector<std ::vector<int> >, you'll have all the memory management
      done for you, the vector will be much easier to pass around between
      functions, and you get exception safety.

      Gavin Deane

      Comment

      • Gavin Deane

        #4
        Re: basic question for pointer


        Neil Cerutti wrote:[color=blue]
        > On 2006-02-22, kathy <yqin_99@yahoo. com> wrote:[color=green]
        > > If I have 2D array like:
        > >
        > > int **p;
        > >
        > > p = new int*[10];
        > >
        > > for(int i=0;i<10;i++)
        > > {
        > > p[i] = new int[10];
        > > }
        > >
        > > To delete the p, should I use:
        > >
        > > for(int i=0;i<10;i++)
        > > {
        > > delete p[i];
        > > }
        > > delete p;
        > >
        > > or just:
        > >
        > > delete p;[/color]
        >
        > The answer is C, none of the above.
        >
        > delete[] p;[/color]

        No, it's answer D.

        for(int i=0;i<10;i++)
        {
        delete [] p[i];
        }
        delete [] p;

        Gavin Deane

        Comment

        • Neil Cerutti

          #5
          Re: basic question for pointer

          On 2006-02-22, Gavin Deane <deane_gavin@ho tmail.com> wrote:[color=blue]
          >
          > Neil Cerutti wrote:[color=green]
          >> On 2006-02-22, kathy <yqin_99@yahoo. com> wrote:[color=darkred]
          >> > If I have 2D array like:
          >> >
          >> > int **p;
          >> >
          >> > p = new int*[10];
          >> >
          >> > for(int i=0;i<10;i++)
          >> > {
          >> > p[i] = new int[10];
          >> > }
          >> >
          >> > To delete the p, should I use:
          >> >
          >> > for(int i=0;i<10;i++)
          >> > {
          >> > delete p[i];
          >> > }
          >> > delete p;
          >> >
          >> > or just:
          >> >
          >> > delete p;[/color]
          >>
          >> The answer is C, none of the above.
          >>
          >> delete[] p;[/color]
          >
          > No, it's answer D.
          >
          > for(int i=0;i<10;i++)
          > {
          > delete [] p[i];
          > }
          > delete [] p;[/color]

          That's assuming she did more allocations more memory than was shown,
          though. She left that part out, so I did, too. ;-)

          --
          Neil Cerutti

          Comment

          • Gavin Deane

            #6
            Re: basic question for pointer


            Neil Cerutti wrote:[color=blue]
            > On 2006-02-22, Gavin Deane <deane_gavin@ho tmail.com> wrote:[color=green]
            > >
            > > Neil Cerutti wrote:[/color][/color]

            The OP's allocation code:
            [color=blue][color=green][color=darkred]
            > >> > int **p;
            > >> >
            > >> > p = new int*[10];
            > >> >
            > >> > for(int i=0;i<10;i++)
            > >> > {
            > >> > p[i] = new int[10];
            > >> > }[/color][/color][/color]

            Your deallocation suggestion:
            [color=blue][color=green][color=darkred]
            > >> delete[] p;[/color][/color][/color]

            My deallocation suggestion:
            [color=blue][color=green]
            > > for(int i=0;i<10;i++)
            > > {
            > > delete [] p[i];
            > > }
            > > delete [] p;[/color]
            >
            > That's assuming she did more allocations more memory than was shown,
            > though. She left that part out, so I did, too. ;-)[/color]

            I think my suggestion covers all the allocations in the OP's code and
            no more, without making any assumptions.

            Am I misunderstandin g what you are saying?

            Gavin Deane

            Comment

            • Neil Cerutti

              #7
              Re: basic question for pointer

              On 2006-02-22, Gavin Deane <deane_gavin@ho tmail.com> wrote:[color=blue]
              >
              > Neil Cerutti wrote:[color=green]
              >> On 2006-02-22, Gavin Deane <deane_gavin@ho tmail.com> wrote:[color=darkred]
              >> >
              >> > Neil Cerutti wrote:[/color][/color]
              >
              > The OP's allocation code:
              >[color=green][color=darkred]
              >> >> > int **p;
              >> >> >
              >> >> > p = new int*[10];
              >> >> >
              >> >> > for(int i=0;i<10;i++)
              >> >> > {
              >> >> > p[i] = new int[10];
              >> >> > }[/color][/color]
              >
              > Your deallocation suggestion:
              >[color=green][color=darkred]
              >> >> delete[] p;[/color][/color]
              >
              > My deallocation suggestion:
              >[color=green][color=darkred]
              >> > for(int i=0;i<10;i++)
              >> > {
              >> > delete [] p[i];
              >> > }
              >> > delete [] p;[/color]
              >>
              >> That's assuming she did more allocations more memory than was shown,
              >> though. She left that part out, so I did, too. ;-)[/color]
              >
              > I think my suggestion covers all the allocations in the OP's code and
              > no more, without making any assumptions.
              >
              > Am I misunderstandin g what you are saying?[/color]

              No. I just spaced out. Thanks for the correction.


              --
              Neil Cerutti

              Comment

              • Puppet_Sock

                #8
                Re: basic question for pointer

                kathy wrote:
                [new/delete question]

                You should always read the FAQ before posting on a news group.
                Your question is answered in the FAQ for this group.



                Basically, you need to keep in mind the rule:

                If you use
                p = new type;

                then you give back the memory so.
                delete p;

                If you use
                p = new type[n];

                then you give back the memory so.
                delete[] p;
                Socks

                Comment

                • Tomás

                  #9
                  Re: basic question for pointer

                  kathy posted:
                  [color=blue]
                  > If I have 2D array like:
                  >
                  > int **p;
                  >
                  > p = new int*[10];
                  >
                  > for(int i=0;i<10;i++)
                  > {
                  > p[i] = new int[10];
                  > }
                  >
                  > To delete the p, should I use:
                  >
                  > for(int i=0;i<10;i++)
                  > {
                  > delete p[i];
                  > }
                  > delete p;
                  >
                  > or just:
                  >
                  > delete p;[/color]


                  This shows you haven't got a firm understanding of what's going on. I'll try
                  give you a hand.

                  Think of a 16-Bit unsigned integer. It looks like the following in memory:

                  0000 0000 0000 0000


                  Now think of an "int *". A pointer variable is just like any other variable
                  -- i.e. it stores data as bits in memory. An "int" variable stores an
                  itegral value in memory, while an "int*" variable store a memory address
                  value in memory. On a particular system, a memory address may be 16 bits. So
                  let's say you define a pointer variable as follows:

                  int* p = 0;

                  It will look like this in memory:

                  0000 0000 0000 0000

                  If you wanted to give it the memory address, 82, it would look like so in
                  memory:

                  0000 0000 0101 0010 (This is the binary value for 82)


                  If you define an array of pointers, like so:

                  int* p[3] = {0, 0, 0};


                  Then they'll be one after the other in memory like this:

                  ----------1st------- ---------2nd-------- ---------3rd--------
                  0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000


                  Let's analyse your code.


                  Line 1: int **p;
                  Line 2:
                  Line 3: p = new int*[10];

                  Line 1 defines a pointer variable. A pointer variable stores a memory
                  address. Let's say it's 16 bits on this system. As of yet it has no value
                  stored in it.

                  Line 3 is an assignment statement. It takes what you have on the right and
                  stores it in the variable on the left. On the right hand side, you're
                  dynamically allocating ten "int *" variables. Think of "new" as a function
                  that returns a memory address; it returns the address of the memory which it
                  has allocated. The "new" statement will allocate ten "int"'s somewhere, like
                  so:

                  0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
                  0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
                  0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
                  0000 0000 0000 0000

                  Then "new" will return the memory address of the first "int*". Let's say
                  that this memory address is 82. At the end of this assignment statement,
                  "p" has the value of 82.

                  When you call "delete", this memory will then be deallocated. All memory
                  which you allocate should eventually be deallocated, like so:

                  Line 1: int **p;

                  Line 2: p = new int*[10];

                  Line 3: delete [] p;


                  Note that the value of "p", i.e. 82, has been passed to "delete". Because of
                  this, "delete" knows which memory to deallocate.

                  Now let's look at your particular example:

                  int **p;

                  p = new int*[10];

                  for( int i=0; i<10; i++ )
                  {
                  p[i] = new int[10];
                  }


                  "p" will still have the value of 82. In the code above, you're storing a
                  memory address in each of the ten pointers. What memory address have you
                  given them... ? Memory addresses which correspond to newly allocated arrays
                  of ten integers. As we saw previously, you eventually have to pass the
                  memory addresses to "delete" so that the memory becomes deallocated. In your
                  loop, you allocate an array of ten integers. The loop runs 10 times, so
                  you've allocated ten arrays of ten integers. (Read the previous sentence
                  again). Therefore you've to call "delete" for each of the ten arrays which
                  you've allocated. Thus you have to do this:


                  int **p;

                  p = new int*[10]; //Allocate once

                  for( std::size_t i = 0 ; i < 10; ++i )
                  {
                  p[i] = new int[10];
                  //Allocate ten times
                  }

                  for( std::size_t i = 0 ; i < 10; ++i )
                  {
                  delete [] p[i];
                  //Deallocate ten times by passing
                  //it the memory addresses.
                  }

                  delete [] p; //Deallocate once


                  Just remember that a pointer variable stores a number which is a memory
                  address. If you don't keep note of this number, then you've nothing to pass
                  to "delete", and then you'll never be able to deallocate the memory you
                  allocated.

                  Hypothetically speaking, if you did the following:

                  int **p;

                  p = new int*[10]; //Allocate once

                  for( std::size_t i = 0 ; i < 10; ++i )
                  {
                  p[i] = new int[10];
                  //Allocate ten times
                  }

                  delete [] p; //Deallocate once


                  Then you will be deallocating the original array which you declared, but you
                  *won't* be deallocating the ten arrays which you declared with your loop.

                  -Tomás

                  Comment

                  Working...