我不太了解传递给函数*mode1
或**mode2
的区别。
我写了一些例子。 (注意:type
可以是任何类型)
[代码1]
#include <stdio.h>
void function (type *vet)
{
/* other */
}
int main ()
{
type *vet;
function (vet)
/* other */
return 0;
}
[代码2]
#include <stdio.h>
void function (type **vet)
{
/* other */
}
int main ()
{
type *vet;
function (&vet)
/* other */
return 0;
}
我知道:第一种情况是指针,第二种情况是指向指针的指针。但是为什么例如在第二种情况下,如果我通过
&vet
可以在function()
中分配内存并在main()
中释放它,而在第一种情况下则不可以呢?我搜寻可以很好地解释我之间差异的人。在这两种情况下我该怎么办?如何以及在哪里分配或重新分配?而且免费吗?并在功能上修改兽医?
最佳答案
原始问题
主要(最重要的)区别是调用函数中的值是否可以更改。
*vet
,可以修改被调用函数中的值。 在第二种情况下,
function()
中的代码可以修改main()
中的实际指针,因此vet
中main()
的值以分配的指针值结束,因此可以释放该指针值。在第一种情况下,main()
中的值未被调用的函数修改,因此main()
无法释放数据。在第一种情况下,您可以在函数中使用
malloc()
或realloc()
,但也应在返回之前释放分配的内存,除非您的代码将值存储在全局变量中(在这种情况下,您可以委托(delegate)其他代码来处理free()
) ,但最好弄清楚是哪个代码负责,在任何情况下使用全局变量可能都不是一个好主意)。或者除非您更改函数签名并返回指向分配数据的指针,否则调用代码应释放该指针。在第二种情况下,您可以在被调用函数中分配或重新分配内存,并将其分配给其他函数使用,并由调用函数释放。
在这两个函数中,您都可以根据需要修改本地
vet
变量。任何函数的任何参数都是如此。您不一定要做的就是在调用函数中修改值;为此,您必须在调用函数中有一个指向值的指针。在第一个函数中,您无法在vet
中更改main()
的值;在第二个中,您可以。在这两个函数中,您都可以更改vet
指向的内容。 (一个小问题是在三种上下文中混合了vet
和main()
这两个不同的功能。这两个函数中的vet
这个名称指向了不同类型的事物。)扩展问题
#include <stdio.h>
#define NUM (10)
struct example
{
/* ... */
}
void dealloc (struct example *pointer)
{
free (pointer);
}
int main()
{
struct example *e;
e = malloc (NUM * sizeof(struct example));
if (e == NULL)
return -1;
struct example *e_copy = e;
dealloc (e_copy);
return 0;
}
此代码是合法的。您将指针的值(的副本)传递给
dealloc()
函数;它将指针传递给free()
,释放释放的内存。返回dealloc()
后,e
和e_copy
中的指针值与以前相同,但是它们不再指向已分配的内存,并且对该值的任何使用都会导致 undefined 的行为。可以为他们分配一个新值。旧值不能可靠地取消引用。#include <stdio.h>
#define NUM (10)
struct example
{
/* ... */
}
int main()
{
struct example *e;
e = malloc (NUM * sizeof(struct example));
if (e == NULL)
return -1;
struct example *e_copy = e;
free (e_copy);
return 0;
}
此示例与上一个示例的区别在于,您可以直接在
free()
中调用main()
,而不是从函数dealloc()
中调用。会有所作为的是:
void dealloc(struct example **eptr)
{
free(*eptr);
*eptr = 0;
}
int main()
{
...
dealloc(&e_copy);
return 0;
}
在这种情况下,
dealloc()
返回后,e_copy
是空指针。您可以再次将其传递给free()
,因为释放空指针是无操作的。两次释放非null指针是 undefined 的行为-通常会导致问题,应不惜一切代价避免。请注意,即使现在,e
包含最初由malloc()
返回的指针;但是使用该指针值会再次导致 undefined 的行为(但是设置e = 0;
或e = NULL;
或e = e_copy;
很好,并且使用e = malloc(sizeof(struct example));
或类似方法也可以。关于c - 传递参数(如* mode1或** mode2)之间的区别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21175693/