Sid*_*ria 0 c string malloc scanf segmentation-fault
我有以下代码段,它分配内存之外的内存:
char *str1 = (char *) malloc(sizeof(char) * BUF_SIZE);
printf ("str1 = ");
scanf("%s", &str1);
int n = strlen(str1);
Run Code Online (Sandbox Code Playgroud)
最初,我得到一个Segmentation Fault在strlen().在玩了gdb之后我才知道那str1是在一个超出界限的地址.下面显示的是gdb输出.
(gdb) print str1
$1 = 0x636261 <Address 0x636261 out of bounds>
Run Code Online (Sandbox Code Playgroud)
注意:断点是在strlen()调用的行上设置的.另外,BUF_SIZE设置为#define BUF_SIZE 10
任何帮助将不胜感激.谢谢 :)
你应该传球str1,而不是&str1到scanf().
scanf()预计一个char *对于"%s"格式; 你传递了一个地址char *.这不会带来快乐.
由于BUF_SIZE非常小 - 只需10,你说 - 你需要使用:
if (scanf("%9s", str1) != 1)
…process error or EOF…
Run Code Online (Sandbox Code Playgroud)
这将保护您免受缓冲区溢出.你应该每次使用时都指定大小%s(除非你使用POSIX修饰符%ms来scanf(),但随后的规则的所有变化).如果不这样做,scanf()可以在不知道的情况下在字符串变量的边界外写入.
您还应检查是否malloc()成功.总是.每次.
请注意,使用GCC和-Wall(或-Wformat)进行编译将指出您的方式的错误.如果你正在使用GCC,你应该总是编译-Wall(最好-Wextra也是 - 我使用更多的选项)来获得更好的错误报告.
对于包含代码的文件,GCC说:
warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
Run Code Online (Sandbox Code Playgroud)
或者在编译时-Werror也会出现"错误" ,我认为这是一种很好的做法.
我注意到GDB告诉我你可能abc在小端(例如英特尔)机器上输入了字符串.该值0x636261对应于此.你覆盖了返回的指针,malloc()因为你传递了地址str1而不是值str1- 留下内存损坏.