我可能是愚蠢的,在这种情况下你需要原谅我......但我不明白这一点。 我正在分配一个16个字符的缓冲区,然后(在一个for循环中)放入23个(!?)随机字符然后打印出来。
我没有得到的是如何将23个字符放入一个malloc为16个字符的缓冲区中...当我将循环更改为24个字符时,我得到一个错误(至少在Linux中使用gcc) )...但为什么不“更早”(17个字符应该打破它......不?)
这是我的示例代码:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
char *buf;
buf = malloc(16 * sizeof(*buf));
if(buf == NULL) exit(1);
for(n = 0; n < 22; n++)
{
buf[n] = rand()%26+'a';
}
buf[n]='\0';
printf("Random string: %s\n", buf);
free(buf);
buf = NULL;
getchar();
return 0;
}
答案 0 :(得分:6)
您正在产生错误,但是就像许多错误一样,它恰好不会被注意到。这就是它的全部内容。
这可能是出于以下几个原因之一 - 可能是免费存储的结构方式,分配之间存在松弛的空间,因为系统需要(或希望)保持可分配块的地址在某些边界上对齐。因此,稍微写一下你分配的块不要干扰免费存储数据结构,但是它们可以进一步干预它们。
你的bug很可能破坏了免费商店经理正在使用的东西,但它恰好在你的简单程序中没有被实际使用,所以错误没有被发现(还)。
答案 1 :(得分:3)
大多数内存分配策略将malloc请求四舍五入到一些量化值。通常是16或32个字节。该量化通常在分配器添加其开销(用于跟踪已分配的块)之后发生,因此通常会发现您可以通过少量字节溢出malloc,而不会对堆造成任何实际损坏,尤其是当分配大小是奇数时。
当然,这不是您想要依赖的东西,它是c运行时库的实现细节,如有更改,恕不另行通知。
答案 2 :(得分:1)
在C中溢出缓冲区时的行为未定义。所以任何事都可能发生,包括什特别是C不是必需的,故意设计不执行边界检查。
如果您遇到任何运行时错误,通常是因为它已被操作系统检测和捕获,而不是由C运行时检测和捕获。只有当访问侵入未映射到进程的内存时,才会发生这种情况。更常见的是,它只会访问属于您的进程但可能被其他内存对象使用的内存;然后,程序的行为将取决于您的代码对无效数据的作用。
答案 3 :(得分:0)
在C中你会逃脱这些事情。稍后,程序的其他部分可能会进入并覆盖您不应使用的区域。所以最好不要测试这些东西。