【问题标题】:Accessing Beyond the malloc()'d Memory访问超出 malloc() 的内存
【发布时间】:2019-05-26 14:19:39
【问题描述】:

我的问题是,当我按照以下代码为 go 变量分配内存时,我可以到达我没有分配的区域(在这种情况下,在第一个区域之后)。那么这个最高到达点的限制是什么,因为当我尝试打印或访问千位时,我会遇到分段错误。 OS(Ubuntu 18.04)如何限制这个区域?

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main(){
    int *go=NULL;
    go = malloc(sizeof(int)*1);
    *go = 190;
    *(go+1)=20;
    *(go+2)=-13;
    *(go+3)=450;
    *(go+4)=140;
    *(go+5)=190;
    printf("%d\n",*(go));
    printf("%d\n",*(go+1));
    printf("%d\n",*(go+2));
    printf("%d\n",*(go+3));
    printf("%d\n",*(go+4));
    printf(">>>%d\n",*(go+5));
    return 0;
}

【问题讨论】:

  • 恐怕这是未定义的行为。
  • "操作系统如何限制这个区域?" - 究竟是哪个操作系统?
  • 在这种情况下是 Ubuntu 18.04.02
  • 这是未定义的行为。在一个系统上,即使尝试访问malloc() 返回的内存末尾之后的内存也可能会崩溃。在另一个系统上,您可能能够顺利通过,因为malloc() 的实现过度分配。在任何特定机器上,行为也可能随着时间而改变,例如,由于其他进程如何使用内存。
  • 访问您的应用程序不拥有的内存是未定义的行为。 IE。任何事情都可能发生。

标签: c memory-management malloc


【解决方案1】:

地址空间由应用程序从操作系统分配。这些分配具有一个粒度,它是硬件、操作系统和 malloc 库参数的函数。很少有架构具有字节粒度。

Malloc 通常不是操作系统接口,而是建立在不太复杂的机制上的高度可用的库。 Malloc 确定它想要扩大和缩小地址空间的粒度,并构造数据结构以以方便的大小跟踪内存。例如,它可能永远不会返回小于 64 字节的对象。您也许可以使用 realloc 确定这一点:分配一组小对象(例如 1 个字节),并找到最接近的两个地址,然后使用 lower 指针调用下面的 grow() 和这个区别。可能你有一个非常规的 malloc,这不起作用....

int grow(void *p, int maxdiff) {
    int i;

    for (i = 2; i < maxdiff; i++) {
        void *t = realloc(p, i);
        if (t != p) {
            return i;
        }
    }
    return -1;
}

有关 malloc() 的优秀教程,请阅读并理解 K&R 的“C 编程语言”中的实现。

【讨论】:

    猜你喜欢
    • 2016-09-27
    • 2016-05-17
    • 1970-01-01
    • 2020-12-14
    • 2011-05-21
    • 1970-01-01
    • 2020-04-09
    • 2018-05-15
    • 2021-09-08
    相关资源
    最近更新 更多