我的malloc函数分配的次数超出了我的预期

RBT*_*RBT 2 c

这是我正在尝试运行的代码.该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程序.

chu*_*ica 5

这是怎么可能的,或者我很幸运没有得到访问冲突错误,即使我实际上进入了我尚未分配给我的程序的内存区域?

当代码到达时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个字节.


Nov*_*zen 5

它的工作原因可能是因为您没有超出当前为该进程分配的内存范围.现代系统通常将内存分配给4千字节的进程.您的第一次分配可能在页面的开头,而您正在窥探的内存可能位于该第一页的未分配的剩余部分中.

操作系统无法检测到无效的内存访问,除非它们超出为您的进程分配的内存范围.就操作系统而言,它为您的流程提供了页面和流程正在使用它.它不关心你的进程使用的malloc例程是否说你的程序"拥有"那个内存.

在获得访问冲突之前,查看您可以阅读的内容可能是一个有趣的实验.在尝试阅读之前,只需循环并打印每个地址.