我有以下代码片段,它将内存分配到边界之外:
char *str1 = (char *) malloc(sizeof(char) * BUF_SIZE);
printf ("str1 = ");
scanf("%s", &str1);
int n = strlen(str1);
最初我在Segmentation Fault
获得strlen()
。在玩了gdb后,我发现str1
位于一个超出界限的地址。下面显示的是gdb输出。
(gdb) print str1
$1 = 0x636261 <Address 0x636261 out of bounds>
注意:断点设置在调用strlen()
的行上。此外,BUF_SIZE
设置为#define BUF_SIZE 10
非常感谢任何帮助。谢谢:))
答案 0 :(得分:8)
您应该将str1
而不是&str1
传递给scanf()
。
scanf()
期望char *
格式为"%s"
;你传递char *
的地址。这不会带来快乐。
由于BUF_SIZE非常小 - 只需10,你说 - 你需要使用:
if (scanf("%9s", str1) != 1)
…process error or EOF…
这将保护您免受缓冲区溢出。每次使用%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=]
或&#39;错误&#39;在使用-Werror
进行编译时,我认为这是一种很好的做法。
我顺便注意到GDB告诉我你可能在小端(例如Intel)机器上输入了abc
作为字符串。值0x636261
对应于此值。您覆盖了malloc()
返回的指针,因为您传递了str1
的地址而不是str1
中的值 - 导致内存损坏。
答案 1 :(得分:4)
您的代码中有几个问题:
scanf("%s", str1);
,放弃&
!malloc()
in C。scanf()
,因为你没有传递任何有关可用缓冲区大小的信息,所以非常危险。最好使用fgets()
。