【问题标题】:Checking if a certain adress in memory is allocated检查是否分配了内存中的某个地址
【发布时间】:2012-01-19 15:17:44
【问题描述】:

我有一个函数可以接收指向 100 个整数的动态数组的指针。但在此之前,我只有 50 个由 malloc 或 calloc 分配,而不是 100 个。

有没有一种方法可以检查是否分配了任何元素(例如第 79 个),而不是想知道这个 SIGSEGV 的实际含义是什么?

我的问题纯粹是理论上的,我没有要显示的实际代码。

【问题讨论】:

  • “检查是否分配了任何元素而不是想知道这个 SIGSEGV 的实际含义”是什么意思?
  • 好吧,如果我在索引中犯了错误——无论是在分配数据还是在访问数据时,我都会得到可能难以理解的 SIGSEGV。就像前段时间一样,我需要一个用于 3 通道图像数据的缓冲区,但我忘记将要分配的字节数乘以 3。所以我分配的缓冲区比预期的要小 3 倍。好吧,valgrind 最后帮助解决了这个问题。
  • 更重要的是,您可能不会收到SIGSEGV
  • 但是这样我就没有错误和一些完全无用的数据了。万岁。

标签: c arrays memory dynamic


【解决方案1】:

不,指针不存储它的大小。您最好将大小和指针存储在结构中并传递它:

typedef struct
{
    size_t size;
    int *ptr;
}  my_data;
void myFunc(my_data *data)
{
    size_t i;
    for(i = 0; i < data->size; i++)
    {
        // data->ptr[i];
    }
}
void myFunc2(my_data *data, size_t index)
{
    if(index < data->size)
    {
        // memory location exists
    }
}

【讨论】:

    【解决方案2】:

    好吧,你可以根据你的描述做这样的事情,给定一个数组并寻找一个索引(这与“任何原始指针”略有不同)。再加上一些工作,甚至可以为任何指针做这样的事情。

    malloc 函数必须存储有关已分配多少的信息。不幸的是,没有标准必须如何做到这一点。一些编译器过度分配并存储紧接在分配数据之前的大小。其他人可能会在地图中存储地址,但其他人可能会做其他事情,你不知道。

    但是,据我所知,大多数(全部?)C 库和至少一个链接器都明确支持重载/挂钩/替换分配函数。
    例如在 GNU C 库中,您可以设置__malloc_hook。而 GNU ld 允许您使用 __wrap_malloc 在链接器级别执行此类操作。

    因此,您可以重载/挂钩mallocfree,该函数只需调用真正的malloc 函数并存储自己在某处分配了多少信息(例如,通过过度分配和使用第一个单词,或任何你喜欢的)。

    然后编写一个接受基指针和索引的函数。该函数查看分配信息(现在您知道在哪里可以找到它!),并且可以简单地检查索引是否在范围内。这不适用于“只是任何指针”。

    另一种适用于“任意指针”的解决方案是编写一个分配器来满足来自不同领域的分配,而不是简单地包装真正的malloc。来自同一个 arena 的所有分配具有相同的分配大小。给定 any 指针,您只需遍历所有 arena 并查看地址是否在 arena 的开始和结束地址内。

    但是,通常应该非常确定分配了多少,这不应该是猜测、随机运气或在运行时计算出来的东西。
    此外,考虑到现成的内存调试器的存在,我怀疑是否真的值得花时间在应用程序端做这样的事情。用valgrind之类的就行了,根本不需要写任何代码。

    【讨论】:

      【解决方案3】:

      不,没有可移植且可靠的方法可以从代码中检查这一点。

      存在一些工具——例如valgrind——可以帮助诊断某些类型的内存错误。

      【讨论】:

        【解决方案4】:

        不,没有。

        这是当你打破你的动态分析工具(例如valgrind),或者使用一个真实的容器来保存它的大小信息。

        【讨论】:

          【解决方案5】:

          几年前我使用了一个库,我忘记了它的名字。使用它,您可以创建 try-catch 块并尝试访问未知数据,例如x[79] 在 try-block 中,如果没有在其中分配内存,则会产生异常。

          【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-07-06
          • 1970-01-01
          • 2012-03-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-07
          • 1970-01-01
          相关资源
          最近更新 更多