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

如果我说:

#include  #include  #include  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。 这是可能的,如果是的话,怎么样?

不可以。在C中,您必须跟踪自己分配的内容。

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

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

我不认为标准有什么用于检查指针是否由malloc返回(并且你只应该将它们传递给free)所以我会说不,你找不到它。 你必须自己跟踪它。

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

 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编写一个包装器,用于跟踪已分配的内存的地址。 然后在您的免费function中,您可以查看该内存是否在列表中。

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

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