如何区分malloced字符串和字符串文字?

时间:2014-11-15 20:32:10

标签: c string char malloc

有没有办法(在纯C中)区分malloc ed字符串和字符串文字,而不知道哪个是哪个?严格地说,我正试图找到一种方法来检查变量是否是一个malloced字符串,如果是,我会释放它;如果没有,我会放手。

当然,我可以向后挖掘代码并确保变量是否为malloc,但以防万一存在简单方法......

编辑:添加行以使问题更具体。

char *s1 = "1234567890"; // string literal
char *s2 = strdup("1234567890"); // malloced string
char *s3;
...
if (someVar > someVal) {
    s3 = s1;
} else {
    s3 = s2;
}
// ...
// after many, many lines of code an algorithmic branches...
// now I lost track of s3: is it assigned to s1 or s2?
// if it was assigned to s2, it needs to be freed;
// if not, freeing a string literal will pop an error

2 个答案:

答案 0 :(得分:8)

  

是否有办法(在纯C中)区分malloced字符串和字符串文字

不是以任何便携方式,不是。不用担心;有更好的选择。

当您使用C语言编写代码时,您会对“谁”拥有内存做出强有力的保证。来电者是否拥有它?那么他们有责任解除分配。被叫方拥有它吗?类似的事情。

你编写的代码非常清楚监管链和所有权链,你不会遇到像“谁解除分配这个问题?”这样的问题。你不应该说:

// after many, many lines of code an algorithmic branches...
// now I forgot about s3: was it assigned to s1 or s2?

解决方案是;别忘了!您可以控制代码,只需查看页面。设计它是防止泄漏内存到其他功能,而没有清楚地理解“嘿,你可以阅读这个东西,但不能保证它在X或Y之后有效。它不是你的记忆,如此对待它。“

或许这是你的记忆。一个很好的例子;您致电strdupstrdup让你知道(通过文档)你有责任解除它返回给你的字符串。你如何做到这一点取决于你,但你最好的办法是尽量缩小范围,尽可能缩短范围。

这需要时间和实践才能成为第二天性。您将创建一些项目,在您熟悉它之前处理内存很差。没关系;你一开始的错误会告诉你要做什么,你将来会避免重复它们(希望如此!)

另外,正如@Lasse在评论中提到的那样,您不必担心s3,它是指针的副本,而不是整个内存块。如果您在s2s3上免费通话,则会导致未定义的行为。

答案 1 :(得分:0)

这是一种实用的方法:

虽然C语言标准没有指示这一点,但是对于代码中给定文字字符串的所有相同事件,编译器会在可执行映像的RO数据部分中生成单个副本

换句话说,代码中每次出现的字符串"1234567890"都会转换为相同的内存地址。

因此,在您要取消分配该字符串的位置,您只需将其地址与文字字符串"1234567890"的地址进行比较即可:

if (s3 != "1234567890") // address comparison
    free(s3);

再次强调这一点,它不是由C语言标准强加的,但它实际上是由任何体面的语言编译器实现的。


<强>更新

以上只是一个直接指向手头问题的实用技巧(而不是这个问题背后的动机)。

严格地说,如果你已经达到了实现中你必须区分静态分配字符串和动态分配字符串的点,那么我倾向于猜测你的初始设计在某个地方有缺陷