你可以确定一个字符串是否可以在C中释放?

时间:2011-06-22 22:36:10

标签: c malloc

如果我说:

#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);
}

然后,显然,程序将打印“okay”,然后死亡,因为“指针被释放未被分配” - 显然,因为字符串是一个字符串文字。

我想编写一个在给定字符串文字时不执行任何操作的函数,但在给定非字符串文字时调用free。这可能吗,如果是的话,怎么样?

5 个答案:

答案 0 :(得分:9)

我认为标准没有任何东西可以检查指针是否由malloc返回(而你只能将它们传递给free)所以我会说不,你找不到它。你必须自己跟踪它。

答案 1 :(得分:5)

没有。在C中,你必须跟踪你自己分配的内容。

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

在Windows上,甚至不要考虑使用[IsBadReadPtr]来测试指针是否指向可读内存 - it should really be called CrashProgramRandomly

答案 2 :(得分:2)

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

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类似),并进行比较你指向这些地区的指针。

答案 3 :(得分:1)

如果您在执行时了解程序的内存映射,那么您可以做一些事情。但更好的办法是进行适当的内存管理。

答案 4 :(得分:1)

您可以为malloc编写一个包装器,用于跟踪已分配内存的地址。然后在您的免费功能中,您可以查看该内存是否在列表中。

除此之外,您可以使用堆,但它甚至不能远程移植。

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