这是我正在尝试运行的代码.该malloc函数分配800个字节.
void DynamicMemoryAllocationUsingMalloc()
{
int* p,i;
if((p = (int*) malloc(800)) == NULL)
{
printf("\n Out of Memory \n");
exit(0);
}
for(i =0;i < 800;i++)
{
printf(" 0x%x", (p + i));
printf(" %d\n", *(p + i));
}
}
Run Code Online (Sandbox Code Playgroud)
但在for循环中,当我打印地址时,我能够安全地跳过800个内存位置(使用整数指针p),每个4字节长(整数的大小),相当于3200字节.这是怎么可能的,或者我很幸运没有得到访问冲突错误,即使我实际上进入了我尚未分配给我的程序的内存区域?我看到垃圾写在所有内存位置的原因显而易见,因为我没有将这些内存位置设置为任何内容.
注意:它是在Windows 7上运行的C程序.
这是怎么可能的,或者我很幸运没有得到访问冲突错误,即使我实际上进入了我尚未分配给我的程序的内存区域?
当代码到达时printf(" %d\n", *(p + 200));,试图读取外部分配的内存.这是未定义的行为 UB.
UB是UB.它可能每天都会发生,或者在下次运行时更改.
你不幸运.幸运的是你的代码会在那里停止.
即使阅读未初始化的int数据也是UB.所以代码尽快有UB(或者可能是实现定义)printf(" %d\n", *(p + 0));.IAC,代码可以在那里停止.
我的malloc函数分配的次数超过了我的意图吗?
这是棘手的一点.调用UB的代码会产生可疑的结果.没有UB的代码没有标准的方法来测试问题.确定这一点的唯一非UB方式是库是否提供了具有答案的函数.
printf("True size %lu\n", (unsigned long) True_size(p));
Run Code Online (Sandbox Code Playgroud)
注意:OP断言int是4个字节.
它的工作原因可能是因为您没有超出当前为该进程分配的内存范围.现代系统通常将内存分配给4千字节的进程.您的第一次分配可能在页面的开头,而您正在窥探的内存可能位于该第一页的未分配的剩余部分中.
操作系统无法检测到无效的内存访问,除非它们超出为您的进程分配的内存范围.就操作系统而言,它为您的流程提供了页面和流程正在使用它.它不关心你的进程使用的malloc例程是否说你的程序"拥有"那个内存.
在获得访问冲突之前,查看您可以阅读的内容可能是一个有趣的实验.在尝试阅读之前,只需循环并打印每个地址.