C函数中的奇怪行为,字符串不会被转移

时间:2011-12-14 23:02:58

标签: c string casting

我有这样的功能:

int foo(void *val){
(char *)val="Long String";
return 0;
}

这个函数被称为:

char str[25];
foo(str);
printf("%s",str);

由于某种原因,我什么都没打印出来。这有什么不对?

3 个答案:

答案 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永远不应被视为用于新代码,绝对是不提倡那些学习如何使用指针和字符数组的人。那种方式就是痛苦。