我有这样的功能:
int foo(void *val){
(char *)val="Long String";
return 0;
}
这个函数被称为:
char str[25];
foo(str);
printf("%s",str);
由于某种原因,我什么都没打印出来。这有什么不对?
答案 0 :(得分:3)
您实际上并没有像您认为的那样复制数据。您所做的只是将参数值更改为指向不同的内存地址。该参数是按值传递的,因此对它的任何更改都不会反映在调用代码中。对于您的尝试,您需要使用strcpy()
或strncpy()
代替,例如:
int foo(char *val)
{
strcpy(val, "Long String");
return 0;
}
或者:
int foo(char *val, int maxlen)
{
strncpy(val, "Long String", maxlen);
return 0;
}
答案 1 :(得分:2)
将指向"Long String"
的指针存储到变量val
中,该变量在堆栈中分配 。变量的生命周期仅在调用foo()
期间延伸。
您不希望将地址存储到堆栈上的"Long String"
。您希望在提供的地址下复制字符串。
你应该这样做:
int foo(void *val){
strcpy((char*)val, "Long String");
return 0;
}
但是,这不安全。您应该将缓冲区的最大大小传递到foo
并使用strncpy()
而不是strcpy()
。
答案 2 :(得分:0)
您没有将任何内容复制到str
。您只是编辑传入的指针值...
调用foo(str)
会创建一个名为void* val
的新临时变量,并将其指向char[0]
。然后,您将val
更改为指向字符串“Long String”的开头。
如果您确实要填充char str[25]
缓冲区,请使用strncpy:
int foo (char* buf)
{ return strncpy (buf, "Long String", 25); }
但是,如果永远发送此例程char[]
,其中少于25个职位,则将出现重大问题。
我还建议,针对刚刚出现的一些建议, strcpy
永远不应被视为用于新代码,绝对是不提倡那些学习如何使用指针和字符数组的人。那种方式就是痛苦。