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()接受另一个参数作为第一个参数,它指定要解析的字符串。