这段代码似乎附加了超出分配范围的字符

This code seems to append characters outside allocated range

本文关键字:分配 范围 字符 段代码 代码      更新时间:2023-10-16

我正在玩一些基本的东西。我是这门语言的新手……所以我警告你,我的问题可能没有被正确地表述出来。谢谢你的帮助。

事情是,在看到www.cplusplus.com/reference/cstdlib/malloc/中的例子后,我发现我自己有这个代码:

#include <stdio.h>
int main (void) {
  char *str;
  str = (char*) malloc(2);
  str[0] ='8';
  str[1] ='8';
  str[2] ='6';
  str[3] ='';
  printf ("%sn",str);
}

和编译:

gcc -O0 -pedantic -Wall test2.cpp

(gcc version 4.7.2)

没有错误,输出886。为什么没有错误?我是否没有越过分配空间的边界?

我没有得到任何错误,我得到了输出886。为什么没有错误?我是否没有越过分配空间的边界?

在这种情况下,代码是好的…为什么参考文献中的例子?在另一种(更可能的)情况下……风险是什么?

谢谢!

你不会得到任何错误,因为C和c++不做边界检查。你覆盖了你没有使用的内存部分,但你很幸运,它不是什么重要的东西。把它比作在墙上钉一排钉子,你知道墙上有钉。如果你错过了钉钉,大多数情况下,你就在石膏上钻个洞,但这样做很危险,因为最终,你会撞到一根带电的电线。

您已超过已分配内存的边界。

然而,printf并不关心你声明的内存大小。它所关心的是它将从头开始并继续直到找到一个0。

您创建的案例是一个未定义的行为。在您分配的区域(可能是另一个变量)之后可能会有一些其他数据,在这种情况下,它将被损坏。如果下一部分是未分配的内存,则可以在没有明显问题的情况下进行转义。如果在您分配的内存之后的内存属于另一个进程,您将看到漂亮而整洁的分段错误。结果可能更糟,所以最好不要在任何地方尝试。

可以在glibc的malloc.c的注释中找到以下内容:

每个分配块的最小开销:每个malloced的4或8字节Chunk有一个隐藏的词来表示开销大小和状态信息。

最小分配大小:4字节ptrs: 16字节(包括4开销)8字节ptrs: 24/32字节(包括4/8开销)

当块被释放时,12(对于4字节的ptrs)或20(对于8字节的
)PTRS(但4字节大小)或24(对于8/8)额外的字节需要;4(8)字节表示尾随大小字段,8(16)字节表示空闲列表指针。因此,最小可分配大小为16/24/32字节。

因为最小分配的大小将是16/24/32,因为它大于3字节,你的程序运行没有错误。