开发者

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 creat开发者_如何学Goe(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!


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 :-)


*&

is not a "pointer-dereference". It's a reference to a pointer. It's needed so the grow function can change the pointer, rather than just what the pointer points to. The alternative would have been a pointer to a pointer, like in the following code.

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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜