C 如何通过函数设置指针引用

C 如何通过函数设置指针引用,c,C,在C语言中,我试图通过将指针发送到函数来设置指针的值,但该值在函数之外不会改变。这是我的密码: #include <stdio.h> void foo(char* str) { char* new_str = malloc(100); memset(new_str, 0, 100); strcpy(new_str, (char*)"new test"); str = new_str; } int main (int argc, char *ar

在C语言中,我试图通过将指针发送到函数来设置指针的值,但该值在函数之外不会改变。这是我的密码:

#include <stdio.h>
void foo(char* str) {

    char* new_str = malloc(100);
    memset(new_str, 0, 100);
    strcpy(new_str, (char*)"new test");

    str = new_str;
}


int main (int argc, char *argv[]) {

    char* str = malloc(100);
    memset(str, 0, 100);

    strcpy(str, (char*)"test");

    foo(str);

    printf("str = %s\n", str);
}  
但这段代码打印出来:

str = test

任何帮助都将不胜感激。提前感谢。

在C中没有按引用传递。如果在C中提供
str
作为函数的参数,则始终传递
str
的当前值,而不是
str
本身

您可以将指向str的指针传递给函数:

void foo(char** pstr) {
    // ...
    *pstr = new_str;
}

int main() {
    // ...
    foo(&str);
}

正如Eiko所说,您的示例代码泄漏了第一次内存分配。您不再使用它,也不再有指向它的指针,因此无法释放它。这是错误的。

您需要使用指针指向未测试的指针:

#include <stdio.h>

void foo(char** str)
{
    char* new_str = malloc(100);
    memset(new_str, 0, 100);
    strcpy(new_str, (char*)"new test");
    if (str) { /* if pointer to pointer is valid then */
        if (*str)   /* if there is a previous string, free it */
            free(*str);
        *str = new_str;  /* return the string */
    }
}


int main (int argc, char *argv[])
{
    char* str = malloc(100);
    memset(str, 0, 100);

    strcpy(str, (char*)"test");

    foo(&str);

    printf("str = %s\n", str);
}
#包括
无效foo(字符**str)
{
char*new_str=malloc(100);
memset(new_str,01100);
strcpy(新测试)(字符*)“新测试”);
如果(str){/*如果指向指针的指针有效,则*/
如果(*str)/*如果存在上一个字符串,请将其释放*/
自由(*str);
*str=new_str;/*返回字符串*/
}
}
int main(int argc,char*argv[])
{
char*str=malloc(100);
memset(str,01100);
strcpy(str,(char*)“测试”);
foo&str;
printf(“str=%s\n”,str);
}

您只是重新分配了一个指针,它是foo中的一个局部变量

如果要复制字符串,请使用strcpy(str,new_str)

您可以将引用传递给指针并重新分配,但这很容易导致内存泄漏,并且很难维护


编辑:关于伪传递引用,请参见Steve的答案。

我是通过从函数返回指针来实现的。在这种情况下没有理由使用malloc,因此您不必担心释放

通用条款4.4.3 c89

char* print_test(char *str)
{
    char *new_str =  "new_test";
    printf("new_str [ %s ]\n", new_str);
    str = new_str;
    return str;
}

int main(void)
{
    char *str = "test";

    printf("str [ %s ]\n", str);

    str = print_test(str);

    printf("str [ %s ]\n", str);

    return 0;
}

你的意思可能是
if(str)
,而不是
if(*str)
。尽管有了这样的更改,但在
str
为null的情况下,
foo
泄漏分配。另外:
free(0)
不做任何操作。但是在调用
free
之前检查null实际上并没有错@Steve:是的。旧习惯很难。也别忘了包括“C中没有通过引用”——不是数组是否被引用传递?@ NaViNoReo基本上,你通过一个指针(至少在语法上)不同于C++中的引用。数组作为参数传递时会衰减为指针,但这仍然不是按引用传递,因为更改指针参数本身的值不会影响数组。@naivnomore:嗯,它们是作为指向第一个元素的指针传递的。通过指针传递几乎满足了通过引用传递的所有实际目的,但这不是一回事。C有一个语法上的怪癖,你可以声明一个函数参数
char[]
。这是char*的同义词,但与数组到指针的衰减相结合,它看起来像是在光线不足的情况下通过引用。区分差异的方法是在函数内的参数上使用
sizeof
,或将其赋值。真实的传递引用将保持类型,就像在C++中传递数组引用时一样。但是,数组中的值也不会通过C传递,这可能导致认为在消除过程中,它们必须通过引用传递。事实上,它们根本不能作为参数传递,只是指向它们的指针。在C语言中使用“传递数组”或“传递字符串”在技术上是不正确的(尽管通常是这样做的,并且通常是可以理解的)。
char* print_test(char *str)
{
    char *new_str =  "new_test";
    printf("new_str [ %s ]\n", new_str);
    str = new_str;
    return str;
}

int main(void)
{
    char *str = "test";

    printf("str [ %s ]\n", str);

    str = print_test(str);

    printf("str [ %s ]\n", str);

    return 0;
}