对传递引用感到困惑

标签 c memory-management memory-leaks pass-by-reference

考虑下面的例子,我试图以 C 方式传递引用:

// Function prototypes
void increment(unsigned* number);

int main()
{
    unsigned* thing;
    increment(thing);
    cout << *thing;
    return 0;
}

void increment(unsigned* number)
{
    number = (unsigned*) malloc(sizeof(unsigned));
    *number = 1;
}

我在 cout << *thing 行遇到程序崩溃.是的,我在这里使用 C++,但我想尝试 C 版本的传递引用,因为我的主要项目是 C 语言。

我通过如下更改代码来修复它:

// Function prototypes
void increment(unsigned** number);

int main()
{
    unsigned* thing;
    increment(&thing);
    cout << *thing;
    return 0;
}

void increment(unsigned** number)
{
    *number = (unsigned*) malloc(sizeof(unsigned));
    **number = 1;
}

现在可以正常工作了,输出为 1,正如我预期的那样。但是,我不明白为什么。我有点困惑为什么在顶部放置一个额外的指针可以解决我的问题。

谢谢!

最佳答案

C 没有传递引用。除数组外,所有参数均按值传递。

在您的第一个版本中,您按值传递变量 thing。在 increment 函数中,它分配内存并将其分配给局部变量 number。但这对调用者的变量没有影响,因为传递的只是它的值,而不是对变量的引用。因此,当 increment 返回时,thing 仍未初始化,并且间接通过它会导致未定义的行为。

如果函数需要修改调用者的变量,调用者必须传递指向变量的指针,而不仅仅是值。这就是您在第二个版本中所做的。然后函数可以通过指针间接更新变量。

当您在 C++ 中使用引用时,这本质上就是幕后发生的事情。在 C 中,您必须显式编写额外级别的间接寻址。

关于对传递引用感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31687076/

相关文章:

C:如何指向calloc数组?

memory-leaks - 如何诊断 Java 8 元空间泄漏?

c - OpenSSL ASN1_item_ex_d2i 内存泄漏

C++克隆并创建以充当虚拟构造函数?

c - 分配一个大块而不是许多小块?

c# - 非托管代码中的内存泄漏?

c - 文件和生成数字,c 编程

java - SDL_SetVideoMode 试图释放一个没有被 malloc 的指针(?)

c - linux 上的 c 函数

c - 使用c中的函数确定数组的最大值