我有一个函数f1
,它需要void指针。从调用者我希望有一个将void指针传递给A
的通用逻辑,它会在内部修改指针。
示例代码粘贴在下面:
#include "stdio.h"
#include "malloc.h"
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);
}
int main()
{
f();
}
但它会导致分段错误。有没有办法让它工作而不改变函数原型f1
?
答案 0 :(得分:5)
C
使用pass-by-value进行函数参数传递。如果必须从函数内部更改传递的变量本身,则需要指向变量的指针。
在你的情况下,它应该是一个指向指针的指针。
否则,在致电f1(a1);
后,在f()
中,a
仍然是NULL
,并且取消引用它会调用undefined behaviour。分割错误是UB的副作用之一。
那就是说,
请malloc()
C
和#include "malloc.h"
中的家人返回see why not to cast。
您不需要malloc()
来使用#include <stdlib.h>
,而是使用stdlib.h
。它在{{1}}头文件中声明。
答案 1 :(得分:1)
您需要修改指针,而不是修改数据。所以你必须传递一个指向指针的指针,就像这个
void f1(void **a)
{
int *b;
b = malloc(sizeof(*b));
printf("b address = %p \n", b);
if (b != NULL)
{
b[0] = 3;
printf("data = %d\n", *(int *) b);
}
*a = b;
}
你这样做的方式,f1
内的指针是传递指针的副本,它们都包含相同的初始值NULL
,你在f()
初始化时使用的值a1
,但您只更改了本地指针的值。
然后取消引用仍为a1
的{{1}},并取消引用NULL
指针,会导致未定义的行为。在您的情况下,行为是发生分段错误。