问题描述
为什么stringParser中的t值显示“ Hello”而不显示主函数?
#include <stdio.h>
char* stringParser(char st[]) {
char temp[100];
int i = 0;
while (st[i] != '\0') {
temp[i] = st[i];
i++;
}
temp[i] = '\0';
char* t = temp;
printf("%s",t);
return t; // Outputs: "Hello"
}
int main() {
char y[] = "Hello";
printf("\n%s",stringParser(y)); //Outputs: "╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠⌠²Ö"
return 0;
}
解决方法
数组temp
仅存在于函数stringParser()
的范围内。指针t
指向数组temp
或换句话说t
保存着temp
的存储地址。当您从函数stringParser()
返回时,数组temp
不再存在,对其进行访问会导致未定义的行为(UB)。您返回指向t
的指针temp
,并将其赋予printf()
。 printf()
取消了对指针的引用,这意味着它想访问t
所指向的数组,但是数组temp
不再存在,因此您拥有UB。
有多种避免UB的方法:
- 制作数组
temp
static
。但这不适用于多线程程序,应在库中避免。 - 使用动态内存分配,使用
temp
或malloc()
为calloc()
数组保留存储空间,但是在您不再使用free()
时必须再次存储需要它。 - 在
main()
中声明数组并将其指针传递到stringParser()
,但要检查大小并确保永远不会出现缓冲区溢出。
非主题:size_t
是数组索引的更好类型,因为可以保证它足够大以容纳所有可能的索引,并且size_t
是无符号的。您的程序易于因将来的更改而导致缓冲区溢出。由于您没有证明给定stringParser()
的字符串必须短于100 char
s。您需要更好地进行记录,检查字符串是否太长,或者动态创建数组以使其足以容纳给定的字符串。