Search code examples
c++pointersdereference

What's the use of pointer-casting a dereferenced pointer?


This question is about code explanation, not code debugging. The code I'm using works. I'm using a public code and I was curious to look at one of their "grow array" template, which looks like this:

  template <typename TYPE>
    TYPE *grow(TYPE *&array, int n, const char *name)
    {
      if (array == NULL) return create(array,n,name);

      bigint nbytes = ((bigint) sizeof(TYPE)) * n;
      array = (TYPE *) srealloc(array,nbytes,name);
      return array;
    }

and the function srealloc looks like this:

void *Memory::srealloc(void *ptr, bigint nbytes, const char *name)
{
  if (nbytes == 0) {
    destroy(ptr);
    return NULL;
  }

  ptr = realloc(ptr,nbytes);
  if (ptr == NULL) {
error();
  }
  return ptr;
}

Please disregard the create function for now. My main question is why do they pointer-cast and dereference array in the template? What's the advantage of that? What if they just didn't have *& at all?

Thanks!


Solution

  • The & token has many meanings, two of which you have confused here. You are not alone! As an operator, it means "address of", which you seem to be comfortable with (this comes from C). But as a type qualifier, it means "reference to", which is quite different. First meaning:

    int x ;
    int* p = &x ; // p = address of x (as in C)
    

    Second meaning:

    void f (int& x) { // x is a reference to an int -- its address is passed to f
      x++ ;
    }
    ...
    int y = 99 ;
    f (y) ; // After this call, y is equal to 100
    

    In this example, the code is equivalent to

    void f (int* x) {
      (*x)++ ;
    }
    ...
    int y = 99 ;
    f (&y) ; // After this call, y is equal to 100
    

    This code doesn't look as clean, but it's easier to understand for C programmers.

    So...the function declaration

    void f (int*& p) ;
    

    (as in your example) means that f can change the value of the int* parameter passed by the calling function. Your sample code looks a bit screwy to me, because why does it need to return the new value of array if it can change the parameter directly? But that is a question of style, and I have learnt not to discuss such matters here :-)