有没有办法(在纯 C 中)区分 malloc
ed 字符串和字符串文字,而不知道哪个是哪个?严格来说,我正在尝试找到一种方法来检查变量是否是错误定位的字符串,如果是,我将释放它;如果没有,我会放手的。
当然,我可以向后挖掘代码并确保变量是否malloc
ed,但以防万一是否存在简单的方法......
编辑:添加行以使问题更具体。
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
有没有办法(在纯 C 中)将错误定位的字符串与字符串文字区分开来,
不是以任何便携式方式,不。 不过不用担心;有更好的选择。
当你用C编写代码时,你这样做的同时,对"谁"拥有内存做出强有力的保证。调用方是否拥有它?然后他们有责任解除分配它。被叫方是否拥有它?类似的事情。
你写的代码非常清楚监管链和所有权,你不会遇到诸如"谁分配这个?你不应该觉得有必要说:
// after many, many lines of code an algorithmic branches...
// now I forgot about s3: was it assigned to s1 or s2?
解决方案是;不要忘记! 您可以控制您的代码,只需稍微查找一下页面即可。 将其设计为防弹,防止将内存泄漏到其他功能,而无需清楚地了解"嘿,你可以阅读这个东西,但不能保证它在 X 或 Y 之后会有效。 这不是你的记忆,就这样对待吧。
或者也许这是你的记忆。 举个例子;你对strdup
的呼唤。 strdup
让您知道(通过文档)您有责任释放它返回给您的字符串。 如何做到这一点取决于你自己,但你最好的办法是将其范围限制在尽可能窄的地方,并且只在必要时保留尽可能短的时间。
这需要时间和实践才能成为第二天性。 在你擅长之前,你会创建一些处理内存不好的项目。 没关系;你一开始的错误会教你什么不该做,你将来会避免重蹈覆辙(希望如此!
此外,正如@Lasse评论中提到的,您不必担心 s3
,这是指针的副本,而不是整个内存块。 如果你在s2
和s3
上拨打免费电话,你最终会得到未定义的行为。
这是一个实用的方法:
尽管 C 语言标准没有规定这一点,但对于代码中给定文本字符串的所有相同匹配项,编译器会在可执行映像的 RO 数据部分中生成单个副本。
换句话说,代码中出现的字符串"1234567890"
的每个匹配项都会转换为相同的内存地址。
因此,在要释放该字符串的位置,您可以简单地将其地址与文字字符串的地址进行比较"1234567890"
:
if (s3 != "1234567890") // address comparison
free(s3);
再次强调这一点,它不是由 C 语言标准强加的,但它实际上由该语言的任何体面的编译器实现。
更新:
以上只是一个实际的技巧,直接涉及手头的问题(而不是这个问题背后的动机)。
严格来说,如果你在实现中已经到了必须区分静态分配的字符串和动态分配的字符串的地步,那么我倾向于猜测你的初始设计在某处是有缺陷的。