Using Reference of Pointers

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • V. de Bellabre

    Using Reference of Pointers

    Hello all,
    I'm currently working on a 3D graphic engine but I'm stuck with a
    small problem on references of pointers.
    Some of my c++ class are complex and use many pointers so I decided to
    force initialisation of objects through their static function Create,
    which has a parameter IN-OUT that will contain the instance of the
    created object.

    Here is a sample that speaks better than words :

    --------------------------------------------------------------------------
    typedef class Texture* PTEXTURE;
    // With this, PTEXTURE& is a reference of a pointer to Texture

    class Texture:
    {
    protected:
    Texture( void ){} // Constructor, do nothing, use Create

    public:
    static void Create( PTEXTURE& ); // PTEXTURE& is a reference of a
    pointer to the texture to create

    // Many other stuff that is not important here

    };

    // Implementation of the Create Function
    void Texture::Create ( PTEXTURE& pTexToCreate )
    {
    pTexToCreate = new Texture; // memory alloc

    // Some init...

    if( badInit )
    {
    delete pTexToCreate;
    pTexToCreate = NULL;
    }
    }

    // A small example of how I use this
    void main( void )
    {
    PTEXTURE pMyTexture;
    Texture::Create ( pMyTexture );
    if( pMyTexture == NULL )
    // Error creating the texture
    }

    --------------------------------------------------------------------------

    Hope this code is clear enough ;)
    Then there is my problem : pMyTexture will never be NULL!! even if
    there IS a problem in the Create function and the line "pTexToCrea te =
    NULL" is executed by the program. Using the debugger shows that
    pTexToCreate is NULL, however when going out of the function,
    pMyTexture has a random value pointing to nothing with sense.
    I really don't understand that, because using references should affect
    the original value passed as a parameter (which is true because when
    initialization is successfull, pMyTexture is pointing to a valid
    Texture). And I don't want to use pointers of pointers to solve this
    problem.

    Can anyone help please ? I just would like pMyTexture to be NULL when
    Create fails :o/

    Vianney
  • Victor Bazarov

    #2
    Re: Using Reference of Pointers

    V. de Bellabre wrote:[color=blue]
    > I'm currently working on a 3D graphic engine but I'm stuck with a
    > small problem on references of pointers.
    > Some of my c++ class are complex and use many pointers so I decided to
    > force initialisation of objects through their static function Create,
    > which has a parameter IN-OUT that will contain the instance of the
    > created object.
    >
    > Here is a sample that speaks better than words :
    >
    > --------------------------------------------------------------------------
    > typedef class Texture* PTEXTURE;
    > // With this, PTEXTURE& is a reference of a pointer to Texture
    >
    > class Texture:[/color]

    What's the colon doing there?
    [color=blue]
    > {
    > protected:
    > Texture( void ){} // Constructor, do nothing, use Create
    >
    > public:
    > static void Create( PTEXTURE& ); // PTEXTURE& is a reference of a
    > pointer to the texture to create
    >
    > // Many other stuff that is not important here
    >
    > };
    >
    > // Implementation of the Create Function
    > void Texture::Create ( PTEXTURE& pTexToCreate )
    > {
    > pTexToCreate = new Texture; // memory alloc
    >
    > // Some init...
    >
    > if( badInit )
    > {
    > delete pTexToCreate;
    > pTexToCreate = NULL;
    > }
    > }
    >
    > // A small example of how I use this
    > void main( void )[/color]
    ^^^^^^^^^^^^^^^ ^^^
    Change this to

    int main()
    [color=blue]
    > {
    > PTEXTURE pMyTexture;[/color]
    ^^^
    Initialise the pointer here, to 0 if there is no better value.
    [color=blue]
    > Texture::Create ( pMyTexture );
    > if( pMyTexture == NULL )
    > // Error creating the texture
    > }
    >
    > --------------------------------------------------------------------------
    >
    > Hope this code is clear enough ;)
    > Then there is my problem : pMyTexture will never be NULL!! even if
    > there IS a problem in the Create function and the line "pTexToCrea te =
    > NULL" is executed by the program. Using the debugger shows that
    > pTexToCreate is NULL[/color]

    Where? Inside the function?
    [color=blue]
    >, however when going out of the function,
    > pMyTexture has a random value pointing to nothing with sense.[/color]

    Seems that your stack gets blown to pieces.
    [color=blue]
    > I really don't understand that, because using references should affect
    > the original value passed as a parameter (which is true because when
    > initialization is successfull, pMyTexture is pointing to a valid
    > Texture). And I don't want to use pointers of pointers to solve this
    > problem.
    >
    > Can anyone help please ? I just would like pMyTexture to be NULL when
    > Create fails :o/[/color]

    Something else can be a problem. If I take the code you posted, get it
    to compile (by fixing it up a bit), it behaves as expected. So, the
    cause of your trouble is not in the code you showed.

    Try to find uninitialised pointers or memory overruns.

    V

    Comment

    • niklasb@microsoft.com

      #3
      Re: Using Reference of Pointers

      V. de Bellabre wrote:[color=blue]
      > Some of my c++ class are complex and use many pointers so I decided[/color]
      to[color=blue]
      > force initialisation of objects through their static function Create,
      > which has a parameter IN-OUT that will contain the instance of the
      > created object.[/color]

      An alternative would be to simply have your Create function return
      a pointer. OUT parameters have their place, but all else being equal,
      simply returning a value is usually more clear.
      [color=blue]
      > typedef class Texture* PTEXTURE;
      > // With this, PTEXTURE& is a reference of a pointer to Texture[/color]

      Personally, I think hiding a pointer behind a typedef like this
      obfuscates more than it clarifies. Yes, I know the Windows header
      files do this all the time, but I suspect that's a holdover from
      the bad old 16-bit days of __near and __far pointers.
      [color=blue]
      > class Texture:
      > {
      > protected:
      > Texture( void ){} // Constructor, do nothing, use Create[/color]

      Is Texture meant to be derived from? If so, you should probably
      add a virtual destructor. If not, the ctor should be private
      instaed of protected.
      [color=blue]
      > public:
      > static void Create( PTEXTURE& ); // PTEXTURE& is a reference of a
      > pointer to the texture to create[/color]

      Or:

      static Texture* Create();

      Problem solved, and no need for reference-to-pointer.
      [color=blue]
      > // Implementation of the Create Function
      > void Texture::Create ( PTEXTURE& pTexToCreate )
      > {
      > pTexToCreate = new Texture; // memory alloc
      >
      > // Some init...
      >
      > if( badInit )
      > {
      > delete pTexToCreate;
      > pTexToCreate = NULL;
      > }
      > }[/color]

      The code above should work as you intended. The only thing I
      can think of is there's undefined behavior somewhere else in
      code you snipped. You might try taking the stripped-down code
      you posted and edit it to be actually compilable, then run it
      to see if the problem still manifests.

      As a matter of style, I'd prefer to see Create return a
      pointer. There's no need for an OUT or IN/OUT parameter here.

      Better yet, why not do the initialization in the ctor as C++
      is meant to be used? If initialization failed, the ctor would
      throw an exception. (My guess is you're using a factory method
      instead because you want to return NULL instead of throwing an
      exception on failure.)
      [color=blue]
      > // A small example of how I use this
      > void main( void )
      > {
      > PTEXTURE pMyTexture;
      > Texture::Create ( pMyTexture );
      > if( pMyTexture == NULL )
      > // Error creating the texture
      > }[/color]

      The return value of main must be int. The above is not legal
      C++, although some compilers accept it.

      Comment

      Working...