C函数不';不返回字符串
为什么这段代码不返回预期的连接字符串,而是返回一个2C函数不';不返回字符串,c,function,strcat,C,Function,Strcat,为什么这段代码不返回预期的连接字符串,而是返回一个2 #include <stdio.h> #include <stdlib.h> #include <string.h> const char * meh() { char meh1[32] = "This "; char meh2[32] = "should work :)"; return strcat(meh1, meh2); } int main() { printf
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char * meh() {
char meh1[32] = "This ";
char meh2[32] = "should work :)";
return strcat(meh1, meh2);
}
int main() {
printf(meh());
return 0;
}
#包括
#包括
#包括
常量字符*meh(){
char meh1[32]=“此”;
char meh2[32]=“应该工作:)”;
返回strcat(meh1、meh2);
}
int main(){
printf(meh());
返回0;
}
因为一旦离开函数meh,meh1将超出范围,它在堆栈上占据的区域将用于printf内部的其他内容。因为一旦离开函数meh,meh1将超出范围,它在堆栈上占据的区域将用于printf内部的其他内容。来自strcat()的手册页,
及
strcat()和函数返回指向结果字符串dest的指针
根据您的用法,dest
是char-meh1[32]
的基址,它是meh()的本地地址。一旦控件从meh()
返回,meh1
将超出范围。因此,printf()
的结果是不确定的[未定义的行为]
要使其工作,请为meh1
使用指针和动态内存分配
比如说,
char *meh1 = NULL;
meh1 = malloc(32);
strcpy(meh1, "this");
以及其余现有的meh()
可以根据需要返回动态分配的指针。在main()
的末尾,您需要free()
返回的指针以避免内存泄漏
此外,还需要使用printf()
like
printf("%s\n", meh());
从strcat()
的手册页
及
strcat()和函数返回指向结果字符串dest的指针
根据您的用法,dest
是char-meh1[32]
的基址,它是meh()的本地地址。一旦控件从meh()
返回,meh1
将超出范围。因此,printf()
的结果是不确定的[未定义的行为]
要使其工作,请为meh1
使用指针和动态内存分配
比如说,
char *meh1 = NULL;
meh1 = malloc(32);
strcpy(meh1, "this");
以及其余现有的meh()
可以根据需要返回动态分配的指针。在main()
的末尾,您需要free()
返回的指针以避免内存泄漏
此外,还需要使用printf()
like
printf("%s\n", meh());
strcat
通过追加字符串meh2
来修改字符串meh1
,然后返回指向第一个字符串的指针。字符串meh1
在函数中声明,因此指针在函数外部无效。这就是为什么你没有得到你期望的结果。相反,您可以这样做:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void meh(char * meh1) {
char meh2[32] = "should work :)";
strcat(meh1, meh2);
return;
}
int main() {
char meh1[32] = "This ";
meh(meh1);
puts(meh1);
return 0;
}
#包括
#包括
#包括
无效meh(字符*meh1){
char meh2[32]=“应该工作:)”;
strcat(meh1,meh2);
回来
}
int main(){
char meh1[32]=“此”;
meh(meh1);
puts(meh1);
返回0;
}
这将产生预期的结果。这是因为字符串meh1
在main
中声明,然后传递给要修改的函数。这意味着修改后的字符串在main
中仍然可用,在调用meh
strcat
函数后,通过追加字符串meh2
修改字符串meh1
,然后返回指向第一个字符串的指针。字符串meh1
在函数中声明,因此指针在函数外部无效。这就是为什么你没有得到你期望的结果。相反,您可以这样做:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void meh(char * meh1) {
char meh2[32] = "should work :)";
strcat(meh1, meh2);
return;
}
int main() {
char meh1[32] = "This ";
meh(meh1);
puts(meh1);
return 0;
}
#包括
#包括
#包括
无效meh(字符*meh1){
char meh2[32]=“应该工作:)”;
strcat(meh1,meh2);
回来
}
int main(){
char meh1[32]=“此”;
meh(meh1);
puts(meh1);
返回0;
}
这将产生预期的结果。这是因为字符串meh1
在main
中声明,然后传递给要修改的函数。这意味着,在调用meh
函数后,修改后的字符串仍然可以在main
中使用,因为strcat()
写入到它的第一个参数中,您实际上返回了指向meh1
的(第一个元素)的指针meh1
和meh2
是具有自动存储持续时间的变量。一旦周围的函数返回,这些变量就会被销毁。访问它们会产生未定义的行为(通常是崩溃)
以下是您可以做的:
const char *meh(void)
{
char meh1[32] = "This ";
char meh2[32] = "should work :)";
char *result;
size_t meh1_len, meh2_len;
/* figure out how long meh1 and meh2 are */
meh1_len = strlen(meh1), meh2_len = strlen(meh2);
/* make a new string with enough space */
result = malloc(meh1_len + meh2_len + 1);
if (result == NULL)
perror("Cannot malloc");
/* Copy the strings */
memcpy(result, meh1, meh1_len);
memcpy(result + meh1_len, meh2, meh2_len + 1);
return (result);
}
当您不再需要meh()
的结果时,不要忘记调用free()
。由于strcat()
写入其第一个参数,您实际上返回了指向meh1
的(第一个元素)的指针meh1
和meh2
是具有自动存储持续时间的变量。一旦周围的函数返回,这些变量就会被销毁。访问它们会产生未定义的行为(通常是崩溃)
以下是您可以做的:
const char *meh(void)
{
char meh1[32] = "This ";
char meh2[32] = "should work :)";
char *result;
size_t meh1_len, meh2_len;
/* figure out how long meh1 and meh2 are */
meh1_len = strlen(meh1), meh2_len = strlen(meh2);
/* make a new string with enough space */
result = malloc(meh1_len + meh2_len + 1);
if (result == NULL)
perror("Cannot malloc");
/* Copy the strings */
memcpy(result, meh1, meh1_len);
memcpy(result + meh1_len, meh2, meh2_len + 1);
return (result);
}
当你不再需要meh()
的结果时,别忘了调用free()
。你在开玩笑:printf(meh())代码>?你在哪里读到的?不要将局部变量(strcat()
returnsmeh1
)返回给调用代码。不要像那样使用printf()
:使用printf(“%s\n”,meh())代码>。返回(指向)局部变量的指针会导致灾难;你会得到未定义的行为,这意味着程序几乎可以做任何事情,发生的任何事情都可以,因为编译器不需要对未定义的行为做任何合理的事情。@Jonathan我很确定他发布了预期结果和实际结果。继续Jonathan Leffler所说的,表单printf(meh());
可能导致不受控制的格式字符串漏洞
如果meh()
返回由用户提供的输入形成的字符串,更多信息如下:我知道我以前的c