Char * p和scanf
我一直试图找出以下代码失败的原因,但我找不到。 请原谅我的无知,让我知道这里发生了什么。
#include int main(void){ char* p="Hi, this is not going to work"; scanf("%s",p); return 0; }
据我所知,我创建了一个指针p到内存大小为29 + 1的连续区域(对于\ 0)。 为什么我不能使用scanf来改变它的内容?
PS请纠正我如果我对char *说错了。
char* p="Hi, this is not going to work";
这不会为你分配内存
这会创建一个String Literal
,每次尝试更改其内容时都会导致Undefined Behaviour
。
使用p
作为scanf
的缓冲区做一些像char * p = malloc(sizeof(char) * 128); // 128 is an Example
char * p = malloc(sizeof(char) * 128); // 128 is an Example
要么
你也可以这样做:
char p[]="Hi, this is not going to work";
我想这就是你真正想做的事情。
请记住,这仍然可能最终成为UB
因为scanf()
不会检查您使用的位置是否确实是有效的可写内存。
记得:
char * p
是一个String Literal,不应修改
char p[] = "..."
分配足够的内存来将String保存在"..."
并可以更改(我的意思是其内容)。
编辑:
避免UB
一个好方法是
char * p = malloc(sizeof(char) * 128); scanf("%126s",s);
p
指向常量字面值,实际上可能驻留在只读存储区中(取决于实现)。 无论如何,试图覆盖这是未定义的行为 。 即它可能导致什么都没有,或者立即崩溃,或者隐藏的内存损坏,这会导致更晚的神秘问题。 不要那样做 。
它崩溃了,因为没有为p分配内存。 为p分配内存,应该没问题。 你拥有的是一个指向p的常量存储区域。 当您尝试在此数据段中编写内容时,运行时环境将引发陷阱,从而导致崩溃。
希望这能回答你的问题
scanf()
解析从stdin(通常是键盘)输入的数据。 我想你想要sscanf()
。
但是, scanf()
的目的是将具有预定义转义序列的字符串分开,而测试字符串没有。 所以这让你有点不清楚你想要做什么。
请注意, sscanf()
接受另一个参数作为第一个参数,它指定要解析的字符串。