简体   繁体   中英

What's the point of having a pointer to pointer to struct as argument?

I'm learning how to program for ALSA in Linux and there's a piece of code like this:

snd_pcm_t * _soundDevice;

bool Init(const char *name)
{
  int i;
  int err;
  snd_pcm_hw_params_t *hw_params;

  if( name == NULL )
  {
      // Try to open the default device
      err = snd_pcm_open( &_soundDevice, "plughw:0,0", SND_PCM_STREAM_PLAYBACK, 0 );
  }

As you can see, it first creates the pointer to the struct snd_pmc_t and name it _soundDevice . Other parts of the code, however, use only the first pointer:

if ((err = snd_pcm_hw_params_any (_soundDevice, hw_params)) < 0)

I understand that a pointer to a struct is helpful to pass as an argument because passing the entire struct as a copy would be bad, and I also understand that this function modifies the content of the struct that the pointer points to, but why should somebody need a pointer to a pointer to a struct?

why should somebody need a pointer to a pointer to a struct?

This most often shows up when you need to pass a pointer into a function in a way that allows the function to change what that pointer points to. One idiomatic C way is to pass the pointer by pointer , resulting in that second level of indirection you're wondering about.

In your example snd_pcm_open modifies its first argument (ie makes _soundDevice point someplace new), whereas snd_pcm_hw_params_any doesn't.

If snd_pcm_open were to take snd_pcm_t* rather than snd_pcm_t** , it wouldn't be able to repoint the first argument in a manner that would propagate back to the caller.

在C语言中,参数传递是按值传递(如果需要,也可以按副本传递),因此,如果要让函数修改传递的参数作为回报,则需要传递其地址。

Having a pointer to a pointer allows the function to modify your local pointer. If you passed just a regular pointer, the function gets that pointer on the stack. If it modifies that value (of the pointer, not the pointed-to data), the value is lost when the function returns the same way that changes to an int passed to a function would be lost. If you instead pass a pointer to a pointer, it can modify your pointer, which will still exist after the function returns.

If, for instance, the function is allocating memory for that structure, it can set your pointer to the address of the newly allocated memory or NULL if the allocation fails. In this case, it looks like this is being used as a second return value. It wants to return an error code as the actual return value and a pointer as a second value.

Some times the target is not to change an object, but to change the pointer that points to it.

Imagine a function 'A' that choses among several functions

int A(someType* funcChosen)
{
     funcChosen = ...; //a pointer to a function
}
someType* myFunc;
int res = A(myFunc);

will modify myFunc . But you want a pointer to that function, not the code (??) of it. So better:

int A(someType** funChosen);
someType* myFunc;
int res = A(&myFunc);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM