Why use double pointer? or Why use pointers to poi

2018-12-31 16:04发布

When should a double pointer be used in C? Can anyone explain with a example?

What I know is that a double pointer is a pointer to a pointer. Why would I need a pointer to a pointer?

标签: c pointers
19条回答
初与友歌
2楼-- · 2018-12-31 16:31

One reason is you want to change the value of the pointer passed to a function as the function argument, to do this you require pointer to a pointer.

In simple words, Use ** when you want to preserve (OR retain change in) the Memory-Allocation or Assignment even outside of a function call. (So, Pass such function with double pointer arg.)

This may not be a very good example, but will show you the basic use:

void allocate(int** p)
{
  *p = (int*)malloc(sizeof(int));
}

int main()
{
  int* p = NULL;
  allocate(&p);
  *p = 42;
  free(p);
}
查看更多
栀子花@的思念
3楼-- · 2018-12-31 16:31

I have used double pointers today while I was programming something for work, so I can answer why we had to use them (it's the first time I actually had to use double pointers). We had to deal with real time encoding of frames contained in buffers which are members of some structures. In the encoder we had to use a pointer to one of those structures. The problem was that our pointer was being changed to point to other structures from another thread. In order to use the current structure in the encoder, I had to use a double pointer, in order to point to the pointer that was being modified in another thread. It wasn't obvious at first, at least for us, that we had to take this approach. A lot of address were printed in the process :)).

You SHOULD use double pointers when you work on pointers that are changed in other places of your application. You might also find double pointers to be a must when you deal with hardware that returns and address to you.

查看更多
倾城一夜雪
4楼-- · 2018-12-31 16:34

Why double pointers?

The objective is to change what studentA points to, using a function.

#include <stdio.h>
#include <stdlib.h>


typedef struct Person{
    char * name;
} Person; 

/**
 * we need a ponter to a pointer, example: &studentA
 */
void change(Person ** x, Person * y){
    *x = y; // since x is a pointer to a pointer, we access its value: a pointer to a Person struct.
}

void dontChange(Person * x, Person * y){
    x = y;
}

int main()
{

    Person * studentA = (Person *)malloc(sizeof(Person));
    studentA->name = "brian";

    Person * studentB = (Person *)malloc(sizeof(Person));
    studentB->name = "erich";

    /**
     * we could have done the job as simple as this!
     * but we need more work if we want to use a function to do the job!
     */
    // studentA = studentB;

    printf("1. studentA = %s (not changed)\n", studentA->name);

    dontChange(studentA, studentB);
    printf("2. studentA = %s (not changed)\n", studentA->name);

    change(&studentA, studentB);
    printf("3. studentA = %s (changed!)\n", studentA->name);

    return 0;
}

/**
 * OUTPUT:
 * 1. studentA = brian (not changed)
 * 2. studentA = brian (not changed)
 * 3. studentA = erich (changed!)
 */
查看更多
墨雨无痕
5楼-- · 2018-12-31 16:35

the following example, that i am giving will give an insight or an intuition about how double pointers work, i will go through the steps

1) try to understand the following statements
   char **str ;

   a) str is of type char ** whose value is an address of another pointer.
   b) *str is of type char * whose value is an address of variable or (it is a string itself).
   c) **str is of type char ,gives the value stored, in this case a character.

the following is the code to which you can relate to above points(a,b,c) to understand

str = (char **)malloc(sizeof(char *) *2); // here i am assigning the mem for two char *
       str[0]=(char *)"abcdefghij"; // assignin the value
       str[1]=(char *)"xyzlmnopqr"; 

now to print the value i.e strings in the array, just look at point b, In case of string the value as well as address is same, so no need to dereference it again.

cout<<*str<<endl;   // abcdefghij;

now to print the next string, come out of one dereference i.e (*) from *str to str and then increment , like shown below

str++;

now print the string

cout<<*str<<endl;        //xyzlmnopqr

now to print only characters in a string, refer to point c)

cout<<**str<<endl;  // prints the first character i.e "a"

now to print the next character of a string i.e "b" come out of 1 dereference operator and increment it i.e going from **str to *str and do *str++

*str++;

now print the character

cout<<**str<<endl;  // prints the second character i.e "b"

since the two arrays("abcdefghij","xylmnopqr") are stored in continous block of memory if same thing is done of incrementing the address, all characters of two strings will get printed

查看更多
零度萤火
6楼-- · 2018-12-31 16:36

Adding to Asha's response, if you use single pointer to the example bellow (e.g. alloc1() ) you will loose the reference to the memory allocated inside the function.

void alloc2(int** p) {
   *p = (int*)malloc(sizeof(int));
   **p = 10;
}

void alloc1(int* p) {
   p = (int*)malloc(sizeof(int));
   *p = 10;
}

int main(){
   int *p;
   alloc1(p);
   //printf("%d ",*p);//value is undefined
   alloc2(&p);
   printf("%d ",*p);//will print 10
   free(p);
   return 0;
}

The reason it occurs like this is that in alloc1 the pointer is passed in by value. So, when it is reassigned to the result of the malloc call inside of alloc1, the change does not pertain to code in a different scope.

查看更多
柔情千种
7楼-- · 2018-12-31 16:36

For example, you might want to make sure that when you free the memory of something you set the pointer to null afterwards.

void safeFree(void** memory) {
    if (*memory) {
        free(*memory);
        *memory = NULL;
    }
}

When you call this function you'd call it with the address of a pointer

void* myMemory = someCrazyFunctionThatAllocatesMemory();
safeFree(&myMemory);

Now myMemory is set to NULL and any attempt to reuse it will be very obviously wrong.

查看更多
登录 后发表回答