你能确定一个字符串在C中是否是自由的吗



如果我说:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char *x;
char *y;
int main() {
        x = malloc(sizeof("Hello, world!"));
        strcpy(x, "Hello world!");
        y = "Hello, world";
        free(x);
        fprintf(stderr, "okay");
        free(y);
}

然后,很明显,程序会打印"OK",然后死亡,因为"释放的指针没有分配"——很明显,因为字符串是字符串文字。

我想写一个函数,当给定字符串文字时什么都不做,但当给定非字符串文字时调用free。这可能吗?如果可能,怎么做?

我不认为标准有任何东西可以检查malloc是否返回了指针(你只应该把它们传递给free),所以我会说没有,你找不到。你必须自己记录。

否。在C中,你必须记录你自己分配了什么。

一些malloc实现(如dlmalloc)提供了一些用于检查堆的额外功能,但您不应该依赖这些功能。dlmalloc具有函数dlmalloc_inspect_all,它将遍历堆并返回给您malloc已分配的所有内存区域,但内存映射块除外。因此,您可以使用它来测试指针是否指向非内存映射的分配,但总的来说,这仍然是个坏主意。

在Windows上,甚至不要考虑使用[IsBadReadPtr]来测试指针是否指向可读内存——它真的应该被称为CrashProgramRandomly

没有可移植的方法。然而,由于大多数实现将堆对象分配到与文字(字符串)数据不同的内存区域,因此,如果给定的字符串指针位于任一区域内,则可以进行有根据的猜测。

static char    x;
bool isStatic(const void *p)
{
    const char *  cp = (const char *)p;
    // Check if the pointer falls within +/-16K of 'x'
    if (cp-16*1024 <= &x  &&  &x <= cp+16*1024)
        return true;
    else
        return false;
}

显然,这有点像黑客。更好的方法是在可执行文件加载到内存后直接访问其.bss.data.text地址(这些是Unix,Win32类似),并将指针与这些区域进行比较。

如果您在执行时了解程序的内存映射,那么您可能会做一些事情。不过,一个更好的想法是进行适当的内存管理。

您可以为malloc编写一个包装器,跟踪已分配内存的地址。然后在你的空闲函数中,你可以看到该内存是否在列表中。

除此之外,你可能可以玩堆,但它甚至不能远程移植。

但为什么不构建某种GC或使用GC库呢。

相关内容

  • 没有找到相关文章

最新更新