Malloc分配超出绑定的内存地址

时间:2015-01-27 15:11:23

标签: c string segmentation-fault malloc scanf

我有以下代码片段,它将内存分配到边界之外:

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

非常感谢任何帮助。谢谢:))

2 个答案:

答案 0 :(得分:8)

您应该将str1而不是&str1传递给scanf()

scanf()期望char *格式为"%s";你传递char *的地址。这不会带来快乐。

由于BUF_SIZE非常小 - 只需10,你说 - 你需要使用:

if (scanf("%9s", str1) != 1)
    …process error or EOF…

这将保护您免受缓冲区溢出。每次使用%s时都应指定大小(除非您使用POSIX修饰符%msscanf(),但规则都会更改)。如果你不知道,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)

您的代码中有几个问题:

  1. 不要在指针上读取 ,你的意思是scanf("%s", str1);,放弃&
  2. Don't cast the return value of malloc() in C
  3. 不要认为分配成功。
  4. 不要使用scanf(),因为你没有传递任何有关可用缓冲区大小的信息,所以非常危险。最好使用fgets()