malloc memory to a pointer to pointer

后端 未结 4 1852
心在旅途
心在旅途 2021-01-24 01:02

I have came across this problem when using pointer to pointer to a char:

void setmemory(char** p, int num)
{
    *p=(char*)malloc(num);
}

    void test(void)
           


        
相关标签:
4条回答
  • 2021-01-24 01:48

    You are only setting the local variable *p here. Remember you are getting a pointer to data, not a pointer-to-pointer-to-data.

    Think of it like this:

    First case:

    int a;
    
    foo(a); // Passes a
    void foo(int b)
    {
      b = 4;    // This only changes local variable, has no effect really
    }
    

    Second case:

    int a;
    foo(&a); // Passes *a
    
    void foo(int *b)
    {
      *b = 4; // This changes the contents of a. As you can see we have not changed the original pointer!
      b = 4; // This changes our local copy of the pointer, not the pointer itself, like in the first case!
    }
    

    Third case

    int *ptr;
    foo(&ptr); // Passes **ptr
    
    void foo(int **b)
    {
      **b = 4; // This changes the data of the passed pointer
      *b = 4; // This changes the passed pointer itself, i.e. it changes ptr. This is what test() is doing, the behavior you are looking for!
      b = 4; // This changes our local copy of a variable, just like the first case!
    }
    
    0 讨论(0)
  • 2021-01-24 01:49

    The orignal code is passing in the location of where the caller wants the string pointer put. If you pass in only a 'char*', the caller will pass by value the contents of the callers location - probably some uninitialized value.

    If the callee has to return a string, or other indirected struct, you need both asterisks so that the callee can return a pointer into the callers pointer variable.

    Does that make sense? It did to me, but then again, I wrote it.

    0 讨论(0)
  • 2021-01-24 01:50

    One thing to note here is - When we say pointers, we generally tend to think in terms of pass by reference but not necessarily. Even pointers can be passed by value

    char* str is local to test and char* p is local to setmemory . So the changes you do in setmemory will not be visible in test if you dont send a pointer to a pointer.

    You can make it work with a single pointer like this

     char * setmemory(char* p, int num) // p is a new pointer but points at the same
                                        // location as str
    {
        p=(char*)malloc(num); // Now, 'p' starts pointing at a different location than 'str'
        strcpy(p ,"hello");  // Copy some data to the locn 'p' is pointing to
        return p; // Oops. The poor `str` is still pointing at NULL :( 
                  // Send him the address of the newly allocated area
    }
    
    void test(void)
    {
        char* str=NULL;
        str=setmemory(str,100); // We are passing a pointer which is pointing to NULL
    
        printf(str); //Now str points to the alloced memory and is happy :)
    }
    
    int main()
    {
        test();
        return 0;
    }
    

    Note that in setmemory we are returning a local pointer, but it is not a problem ( no dangling pointer problems ) as this pointer points to a location on heap and not on stack

    0 讨论(0)
  • 2021-01-24 01:54

    You want to change the pointer, i.e., the function need a reference, not a value. In C, this is done by giving the address (pointer) to the variable that is by change a pointer itsself. Thus, one pointer is for referencing, the other for you porgram logic.

    0 讨论(0)
提交回复
热议问题