Malloc 分配超出范围的内存地址
Malloc Allocates Out of Bound Memory Address
我有下面的代码片段,它分配了超出范围的内存:
char *str1 = (char *) malloc(sizeof(char) * BUF_SIZE);
printf ("str1 = ");
scanf("%s", &str1);
int n = strlen(str1);
最初我在 strlen()
中得到一个 Segmentation Fault
。在玩过 gdb 之后,我开始知道 str1
位于一个越界的地址。下面显示的是 gdb 输出。
(gdb) print str1
= 0x636261 <Address 0x636261 out of bounds>
注意:断点设置在调用strlen()
的那一行。此外,BUF_SIZE
设置为 #define BUF_SIZE 10
如有任何帮助,我们将不胜感激。谢谢:)
您应该将 str1
而不是 &str1
传递给 scanf()
。
scanf()
期望 "%s"
格式的 char *
;你传递了一个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=]
或 'error' 也用 -Werror
编译,我认为这是很好的做法。
我顺便注意到 GDB 告诉我您可能在小端(例如 Intel)机器上输入了 abc
作为字符串。值 0x636261
对应于此。您覆盖了 malloc()
返回的指针,因为您传递了 str1
的地址而不是 str1
中的值——导致内存损坏。
你的代码有几个问题:
- 不要通过 指针读取字符串 ,您的意思是
scanf("%s", str1);
,删除 &
!
- Don't cast the return value of
malloc()
in C.
- 不要假设分配成功。
- 不要为此使用
scanf()
,这非常危险,因为您没有向它传递有关可用缓冲区大小的任何信息。最好用fgets()
.
我有下面的代码片段,它分配了超出范围的内存:
char *str1 = (char *) malloc(sizeof(char) * BUF_SIZE);
printf ("str1 = ");
scanf("%s", &str1);
int n = strlen(str1);
最初我在 strlen()
中得到一个 Segmentation Fault
。在玩过 gdb 之后,我开始知道 str1
位于一个越界的地址。下面显示的是 gdb 输出。
(gdb) print str1
= 0x636261 <Address 0x636261 out of bounds>
注意:断点设置在调用strlen()
的那一行。此外,BUF_SIZE
设置为 #define BUF_SIZE 10
如有任何帮助,我们将不胜感激。谢谢:)
您应该将 str1
而不是 &str1
传递给 scanf()
。
scanf()
期望 "%s"
格式的 char *
;你传递了一个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=]
或 'error' 也用 -Werror
编译,我认为这是很好的做法。
我顺便注意到 GDB 告诉我您可能在小端(例如 Intel)机器上输入了 abc
作为字符串。值 0x636261
对应于此。您覆盖了 malloc()
返回的指针,因为您传递了 str1
的地址而不是 str1
中的值——导致内存损坏。
你的代码有几个问题:
- 不要通过 指针读取字符串 ,您的意思是
scanf("%s", str1);
,删除&
! - Don't cast the return value of
malloc()
in C. - 不要假设分配成功。
- 不要为此使用
scanf()
,这非常危险,因为您没有向它传递有关可用缓冲区大小的任何信息。最好用fgets()
.