malloc内存到指针的指针

时间:2012-04-18 13:38:04

标签: c string pointers

当使用指向char的指针时,我遇到了这个问题:

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

    void test(void)
    {
        char* str=NULL;
        setmemory(&str,100);
        strcpy(str,"hello");
        printf(str);
    }

int main()
{
    test();
    return 0;
}

上面的代码是正确的,但我无法弄清楚为什么在这里使用指针char ** p的指针?为什么只使用指向char的指针?所以我把这个片段改成下面,发现它不起作用,谁能告诉我为什么?谢谢!

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

void test(void)
{
    char* str=NULL;
    setmemory(str,100);
    strcpy(str,"hello");
    printf(str);
}

int main()
{
    test();
    return 0;
}

4 个答案:

答案 0 :(得分:3)

有一点需要注意的是 - 当我们说指针时,我们通常倾向于用pass by reference来思考,但不一定。偶数指针可以是passed by value

char* str位于test的本地,char* p位于setmemory的本地。因此,如果您不向指针发送指针,则setmemory中的更改将无法在test中显示。

你可以使用像这样的单个指针

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

请注意,在setmemory中我们返回一个本地指针,但它不是问题(没有悬空指针问题),因为这个指针指向堆上的位置而不是堆栈

答案 1 :(得分:0)

您想要更改指针,即函数需要引用,而不是值。在C中,这是通过向变量提供地址(指针)来完成的,该变量是通过自己改变指针。因此,一个指针用于引用,另一个用于引用逻辑。

答案 2 :(得分:0)

您只在这里设置局部变量* p。请记住,您正在获取指向数据的指针,而不是指针指向数据的指针。

这样想:

第一种情况:

int a;

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

第二种情况:

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!
}

第三种情况

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!
}

答案 3 :(得分:0)

orignal代码传入调用者想要放置字符串指针的位置。如果只传入'char *',调用者将通过值传递调用者位置的内容 - 可能是一些未初始化的值。

如果被调用者必须返回一个字符串或其他间接结构,则需要两个星号,以便被调用者可以将指针返回到调用者指针变量。

这有意义吗?它对我有用,但后来又写了。