Pointer to an array of pointers

Discussion in 'C++' started by Andy Gibbs, Feb 13, 2009.

  1. Andy Gibbs

    Andy Gibbs Guest

    Hello!

    Please could someone help me with what is probably a trivial problem, but is
    definitely tying me in knots!

    I have a class MyObject, and I need to create a pointer to an array of
    pointers to this class. I think I am correct with the definition of...

    MyObject* (*pointer)[];

    which I take to mean a pointer to an array of MyObject pointers.

    I believe I am also correct with my accessor function:

    MyObject& item(int index) {
    return *((*pointer)[index]);
    }

    However, I am having real difficulty working out how to use new and delete
    with my pointer. So the following doesn't work:

    pointer = new MyObject*[size];
    for (int i = size; i-->0;)
    (*pointer) = new MyObject(...);

    Because the first line fails compile with "cannot convert DbString** to
    DbString*(*)[] in assignment". (I am using GCC 4.1.2.)

    The following use of delete compiles, but I am not sure it does what I think
    (hope?) it does!

    for (int i = size; i-->0;)
    delete (*pointer);
    delete[] pointer; // should this be delete[] *pointer ?


    Please, any help will be very gratefully appreciated!

    Andy.
    Andy Gibbs, Feb 13, 2009
    #1
    1. Advertising

  2. * Andy Gibbs:
    >
    > Please could someone help me with what is probably a trivial problem, but is
    > definitely tying me in knots!
    >
    > I have a class MyObject, and I need to create a pointer to an array of
    > pointers to this class. I think I am correct with the definition of...
    >
    > MyObject* (*pointer)[];
    >
    > which I take to mean a pointer to an array of MyObject pointers.


    Use a std::vector.

    std::vector<MyObject*> arr;


    > I believe I am also correct with my accessor function:
    >
    > MyObject& item(int index) {
    > return *((*pointer)[index]);
    > }
    >
    > However, I am having real difficulty working out how to use new and delete
    > with my pointer. So the following doesn't work:
    >
    > pointer = new MyObject*[size];
    > for (int i = size; i-->0;)
    > (*pointer) = new MyObject(...);
    >


    Use a std::vector instead.


    > Because the first line fails compile with "cannot convert DbString** to
    > DbString*(*)[] in assignment". (I am using GCC 4.1.2.)


    Good.


    > The following use of delete compiles, but I am not sure it does what I think
    > (hope?) it does!
    >
    > for (int i = size; i-->0;)
    > delete (*pointer);
    > delete[] pointer; // should this be delete[] *pointer ?
    >
    >
    > Please, any help will be very gratefully appreciated!


    Use a std::vector instead.


    Cheers & hth.,

    - Alf
    Alf P. Steinbach, Feb 13, 2009
    #2
    1. Advertising

  3. Andy Gibbs

    Andy Gibbs Guest

    Alf P. Steinbach wrote:

    > * Andy Gibbs:
    >>
    >> Please could someone help me with what is probably a trivial problem, but
    >> is definitely tying me in knots!
    >>
    >> I have a class MyObject, and I need to create a pointer to an array of
    >> pointers to this class. I think I am correct with the definition of...
    >>
    >> MyObject* (*pointer)[];
    >>
    >> which I take to mean a pointer to an array of MyObject pointers.

    >
    > Use a std::vector.
    >
    > ...



    Alf, thanks for your reply. I have considered the use of a number of
    dynamic array implementations, but unfortunately they really aren't
    suitable in my application.

    I can understand that the way the question is posed leads to such an answer,
    because I simplified it to make it understandable, but using std::vector
    won't work in this case -- sorry, I should have said so in the
    question! ;o)

    Thanks
    Andy
    Andy Gibbs, Feb 13, 2009
    #3
  4. Andy Gibbs <> writes:

    > Hello!
    >
    > Please could someone help me with what is probably a trivial problem, but is
    > definitely tying me in knots!
    >
    > I have a class MyObject, and I need to create a pointer to an array of
    > pointers to this class. I think I am correct with the definition of...
    >
    > MyObject* (*pointer)[];
    >
    > which I take to mean a pointer to an array of MyObject pointers.


    You can skip the array. A pointer is automatically a pointer to an array.

    class MyObject {
    public:
    MyObject(){};
    };

    int main(){
    MyObject** pointer;

    pointer=new MyObject* [4];

    pointer[0]=new MyObject();
    pointer[1]=new MyObject();
    pointer[2]=new MyObject();
    pointer[3]=new MyObject();

    delete pointer[0];
    delete pointer[1];
    delete pointer[2];
    delete pointer[3];

    delete [] pointer;

    return(0);
    }

    /*
    -*- mode: compilation; default-directory: "/tmp/" -*-
    Compilation started at Fri Feb 13 13:33:25

    SRC="/tmp/a.c++" ; EXE="a" ; g++ -g3 -ggdb3 -o ${EXE} ${SRC} && ./${EXE} && echo status = $?
    status = 0

    Compilation finished at Fri Feb 13 13:33:25

    */


    > I believe I am also correct with my accessor function:
    >
    > MyObject& item(int index) {
    > return *((*pointer)[index]);
    > }


    Since you have an array of pointers, why do you want to return a reference?


    > However, I am having real difficulty working out how to use new and delete
    > with my pointer. So the following doesn't work:
    >
    > pointer = new MyObject*[size];
    > for (int i = size; i-->0;)
    > (*pointer) = new MyObject(...);
    >
    > Because the first line fails compile with "cannot convert DbString** to
    > DbString*(*)[] in assignment". (I am using GCC 4.1.2.)


    See the difference between your post and my answer. Your post doesn't
    contain full source code, compilable. Mine does. If it had an error,
    you could debug it.


    > The following use of delete compiles, but I am not sure it does what I think
    > (hope?) it does!
    >
    > for (int i = size; i-->0;)
    > delete (*pointer);
    > delete[] pointer; // should this be delete[] *pointer ?


    No. You want to delete the memory pointed to by pointer, not by
    *pointer (which is pointer[0]). See my code.


    --
    __Pascal Bourguignon__
    Pascal J. Bourguignon, Feb 13, 2009
    #4
  5. * Andy Gibbs:
    > Alf P. Steinbach wrote:
    >
    >> * Andy Gibbs:
    >>> Please could someone help me with what is probably a trivial problem, but
    >>> is definitely tying me in knots!
    >>>
    >>> I have a class MyObject, and I need to create a pointer to an array of
    >>> pointers to this class. I think I am correct with the definition of...
    >>>
    >>> MyObject* (*pointer)[];
    >>>
    >>> which I take to mean a pointer to an array of MyObject pointers.

    >> Use a std::vector.
    >>
    >> ...

    >
    >
    > Alf, thanks for your reply. I have considered the use of a number of
    > dynamic array implementations, but unfortunately they really aren't
    > suitable in my application.
    >
    > I can understand that the way the question is posed leads to such an answer,
    > because I simplified it to make it understandable, but using std::vector
    > won't work in this case


    Why?

    - Alf
    Alf P. Steinbach, Feb 13, 2009
    #5
  6. Andy Gibbs

    Fraser Ross Guest

    > However, I am having real difficulty working out how to use new and
    > delete
    > with my pointer. So the following doesn't work:
    >
    > pointer = new MyObject*[size];
    > for (int i = size; i-->0;)
    > (*pointer) = new MyObject(...);


    The return type of operator new here must be MyObject*.

    Fraser.
    Fraser Ross, Feb 13, 2009
    #6
  7. On Feb 13, 9:37 am, Andy Gibbs <> wrote:
    > Hello!
    >
    > Please could someone help me with what is probably a trivial problem, but is
    > definitely tying me in knots!
    >
    > I have a class MyObject, and I need to create a pointer to an array of
    > pointers to this class. I think I am correct with the definition of...
    >
    > MyObject* (*pointer)[];
    >
    > which I take to mean a pointer to an array of MyObject pointers.


    I assume you take that to mean a "dynamic array" of any size, but
    there is no such built-in type in C++. Actually, using empty square
    brackets in a type expression means that the type is incomplete (i.e.
    not fully specified).

    There is severe restrictions on how you can use incomplete types. In
    particular there is no implicit conversion from a pointer to a
    complete type to a pointer to an incomplete type, e.g.

    int (*a) [2];
    int (*p) [] = a; // error: cannot convert from 'int (*)[2]' to 'int
    (*)[]'

    > ...
    > However, I am having real difficulty working out how to use new and delete
    > with my pointer. So the following doesn't work:
    >
    > pointer = new MyObject*[size];


    The type of the right hand side is not what you seem to expect; new
    does not return a pointer to an array (MyObject* (*) [size]). Even if
    it did, you could not assign that pointer to your pointer, because the
    latter points to an incomplete type as I explained above.

    Actually, the new operator has very irregular behaviour for array
    types:

    typedef struct Scalar {int i;};
    Scalar* s = new Scalar; // works; returns Scalar*

    typedef int Array [1];
    Array* a = new Array; // fails; returns int**

    The new operator will never allocate an array and return a pointer to
    it. For arrays it will instead allocate a number of contiguous
    elements and return a pointer to the first element. This is an
    irregular feature stemming from the unfortunate reuse of the square
    brackets to pass an argument to new at run-time.

    If the size of your array (and hence its type) is known at compile-
    time, then you can circumvent these irregularities by using an array
    wrapper such as tr1::array:

    typedef std::tr1::array <MyObject*, size> A;
    A* pointer = new A; // works; returns A*

    If the size is not known until run-time you will have to scrap arrays
    and use pointers, or preferably a container type such as std::vector,
    instead.

    General tip: Use typedef to simplify type expressions.

    Regards,
    Vidar Hasfjord
    Vidar Hasfjord, Feb 13, 2009
    #7
  8. On Feb 13, 8:01 pm, Vidar Hasfjord <>
    wrote:
    >   Array* a = new Array; // fails; returns int**


    Sorry, typo. Of course that should be

    Array* a = new Array; // fails; returns int*
    Vidar Hasfjord, Feb 13, 2009
    #8
  9. Andy Gibbs <> wrote:
    > Alf P. Steinbach wrote:
    >
    >> * Andy Gibbs:
    >>>
    >>> Please could someone help me with what is probably a trivial problem, but
    >>> is definitely tying me in knots!
    >>>
    >>> I have a class MyObject, and I need to create a pointer to an array of
    >>> pointers to this class. I think I am correct with the definition of...
    >>>
    >>> MyObject* (*pointer)[];
    >>>
    >>> which I take to mean a pointer to an array of MyObject pointers.

    >>
    >> Use a std::vector.
    >>
    >> ...

    >
    >
    > Alf, thanks for your reply. I have considered the use of a number of
    > dynamic array implementations, but unfortunately they really aren't
    > suitable in my application.
    >
    > I can understand that the way the question is posed leads to such an answer,
    > because I simplified it to make it understandable, but using std::vector
    > won't work in this case -- sorry, I should have said so in the
    > question! ;o)
    >
    > Thanks
    > Andy
    >


    It seems to me that the STL was designed to do exactly the kind of thing
    you are trying to do. Please post more details. If it really is the case
    that the particular kind of array of pointers (or pointer to it) that you
    need cannot be handled with std:vector, then it will be of interest (to me
    at least).

    --
    Chris Gordon-Smith
    London
    www.simsoup.info
    Chris Gordon-Smith, Feb 13, 2009
    #9
  10. Andy Gibbs

    James Kanze Guest

    On Feb 13, 1:37 pm, (Pascal J. Bourguignon)
    wrote:
    > Andy Gibbs <> writes:


    > > Please could someone help me with what is probably a trivial
    > > problem, but is definitely tying me in knots!


    > > I have a class MyObject, and I need to create a pointer to
    > > an array of pointers to this class. I think I am correct
    > > with the definition of...


    > > MyObject* (*pointer)[];


    > > which I take to mean a pointer to an array of MyObject pointers.


    > You can skip the array. A pointer is automatically a pointer
    > to an array.


    Rather, a pointer might be a pointer to an object, or a pointer
    to the first element of an array. C++ inherits this (serious)
    defect from C. What he's trying to do is sensible and logical,
    but it doesn't fit in with the rest of the language. The
    problem is that new (MyObject*)[n] doesn't return a pointer to
    an array, (type MyObject *(*)[]), but a pointer to the first
    element of the array (type MyObject **). (This is also,
    indirectly, the reason why we need delete[]. If the language
    weren't so horribly broken in this regard, the type of the
    pointer would give the compiler all the information it needs.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Feb 14, 2009
    #10
    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. sangeetha

    Array of pointer Vs Pointer to Array

    sangeetha, Oct 8, 2004, in forum: C Programming
    Replies:
    9
    Views:
    340
    Tim Rentsch
    Oct 9, 2004
  2. mann!

    pointer to array v/s array of pointers

    mann!, Feb 25, 2005, in forum: C Programming
    Replies:
    6
    Views:
    323
    E. Robert Tisdale
    Feb 26, 2005
  3. erfan

    Array of pointer and pointer of array

    erfan, Jan 28, 2008, in forum: C Programming
    Replies:
    6
    Views:
    665
    Martin Ambuhl
    Jan 28, 2008
  4. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    657
  5. , India

    pointer to an array vs pointer to pointer

    , India, Sep 20, 2011, in forum: C Programming
    Replies:
    5
    Views:
    445
    James Kuyper
    Sep 23, 2011
Loading...

Share This Page