在C11规范中,%p
的参数类型在void **
函数的情况下必须为scanf()
,但我无法确定如何输入地址并存储它进入void **
。
事实上,如果我试图做:
void **p;
scanf("%p", p);
我遇到了分段错误。
P.S。 C11规范:
相应的参数应该是指向void
的指针
答案 0 :(得分:6)
void **p;
scanf("%p", p);
与
相同的原因不起作用int *i;
scanf("%i", i);
不起作用 - 你正在写一个未初始化的指针(或告诉scanf
写一个,至少)。
这有效:
int i;
scanf("%i", &i);
这样做:
void *p;
scanf("%p", &p);
答案 1 :(得分:1)
您没有初始化p
。尝试:
void *p;
scanf("%p", &p);
这将使用p
的地址,该地址有效。
答案 2 :(得分:1)
注意:原始帖子没有提及c11
标准。
好吧,根据c99
规范文件,第7.19.6章。 1 2,段落 8 12,
p
匹配实现定义的序列集,应该是 与可能由%p转换产生的序列集相同 fprintf功能。相应的参数应该是指向a的指针 指向void的指针。输入项将转换为指针值 实现定义的方式。如果输入项是先前转换的值 在同一程序执行期间,结果的指针应进行比较 等于该值;否则%p转换的行为是未定义的。
因此,它不是 void **
,而是void *
。
接下来,您出现分段错误的原因是在p
中使用了未初始化的指针scanf()
。在使用[传递给p
作为参数]之前,您没有为scanf()
分配内存。
正如其他人的建议,你可以很好地使用像
这样的东西void *p;
scanf("%p", &p);
此处,&p
值实际为pointer to a pointer to void
并且具有已定义的地址。
答案 3 :(得分:0)
标准说%p
应该有void *
类型参数。您需要将p
声明为void *
然后
scanf("%p", &p);
您遇到段错误的原因是因为在void **p
中,p
并未指向任何位置。