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