void指针作为参数

以下C片段:

[...] void f1(void* a){ printf("f(a) address = %p \n",a); a = (void*)(int*)malloc(sizeof(int)); printf("a address = %p \n",a); *(int*)a = 3; printf("data = %d\n",*(int*)a); } void f(void){ void* a1=NULL; printf("a1 address = %p \n",a1); f1(a1); printf("a1 address = %p \n",a1); printf("Data.a1 = %d\n",*(int*)a1); } [...] 

结果是

 a1 address = (nil) f(a) address = (nil) a address = 0xb3f010 data = 3 a1 address = (nil) Segmentation fault (core dumped) 

为什么a1不保留函数中分配给它的地址?

因为这是C,所以不能通过引用传递指针而不传入指针指针(例如, void **而不是void *指向指针)。 您需要返回新指针。 怎么了:

 f(a1); 

将指针的值( NULL )作为a的堆栈参数值。 a获取此值,然后重新分配一个新值( malloc ed地址)。 当它按值传递时, a1没有任何变化。

如果这是C ++,你可以通过引用传递指针来实现你想要的:

 void f(void *&a); 

将指针指向a1传递给您的函数,您无法更改a1指向的位置。 指针按值传递 ,因此在f1您只需更改a所持地址的副本。 如果要更改指针,即为传入的指针分配新内存,则需要将指针传递给指针

 void f1(void **a) { // ... *a = malloc(sizeof(int)); // ... 

要通过函数调用更改变量,函数需要具有与参数相关的引用语义 。 C没有本机引用变量,但可以通过获取地址和传递指针来实现引用语义。

通常:

 void mutate_thing(Thing * x) // callee accepts pointer { *x = stuff; // callee derefences ("*") } int main() { Thing y; mutate_thing(&y); // caller takes address-of ("&") } 

在你的情况下, Thingvoid *

 void f(void ** pv) { *pv = malloc(12); // or whatever } int main() { void * a1; f(&a1); } 

基于Kerrek SB的例子,我带来了这个来演示void指针到指针作为参数以及如何使用它。

 #include  void test(void ** jeez) { *jeez = (void *) (int) 3; } int main (int argc, char* argv[]) { void *a; test(&a); int b = *(int *)&a; printf("value returned = %d\n", b); return 0; }