经常为字符串重新分配内存是一个好习惯吗?

时间:2016-08-14 10:03:47

标签: c string malloc realloc

我有格式字符串,我解析它比用输入参数替换格式说明符。现在我考虑如何在替换参数后为这样的结果字符串分配内存。我可以像格式字符串一样分配这个字符串,而不是替换其他字符串  任何长期的%s都需要在一些不确定的融合中重新分配这个字符串,这使得有必要在代码中进行一些不优雅的计算。 所以我想我可以分配这个从格式字符串创建的字符串,只需char by char,每次重新分配它,如:

/*** for loop traversing next chars in format string ***/
// if new char 
str = realloc(str, sizeof(*str) +1); 
// if %s 
str = realloc(str, sizeof(*str) + strlen(in_str)); 
// if %d 
str = realloc(str, sizeof(*str) + strlen(d_str)); 

3 个答案:

答案 0 :(得分:5)

通常内部库代码处理可变字符串/数组/列表的长度/其他任何其他2 ^ n步骤 - 即当你有4个字节的内存并需要分配5时,它实际上分配8。这将减少~log(n)操作的realloc()调用次数,这是很昂贵的。 但是,可能还有其他优化,具体取决于库。

答案 1 :(得分:2)

我不会评论其他答案中充分解决的代码问题。

为每个单独的字符串扩展行为调用realloc并不一定是不好的做法。它看起来好像它可能表现不好,为了解决这个问题,你可以实现一个方案,以较大的增量增加字符串,减少频率。但是,您如何知道realloc内部尚未执行此类操作?例如,您可能认为通过将128字节字符串增加到256字节然后再增加到512而不是一次增加一个字符来实现聪明。但如果这些恰好是唯一可用的malloc内部块大小,那么realloc也无法帮助您逐步完成相同的大小。那么,保存原始realloc次来电话数怎么样?但是这些只是被更聪明的字符串增长逻辑的调用所取代。

如果此格式化字符串构建循环的性能很重要,则对其进行概要分析。制作一个版本,以减少realloc操作和配置文件。在您编写的所有目标平台上以及性能都很重要的地方进行比较。

如果性能不重要,则针对良好的结构,可维护性和代码重用等属性进行优化。构建格式字符串的函数不必知道字符串内存管理。它需要一个抽象接口来处理动态字符串。该接口可以通过在其尾部添加另一个字符串的副本来提供一个很好的函数来就地更改字符串。除了格式字符串生成器之外的函数可以使用这些字符串操作。

字符串管理代码可以在一个地方决定每次字符串长度发生变化时是否调用realloc,或者它是否与长度分开跟踪存储大小,从而减少{ {1}}来电。

答案 2 :(得分:1)

这样的代码:

str = realloc(str, sizeof(*str) +1);

很糟糕。如果realloc失败,则会返回NULL但不会free(str)。换句话说 - 内存泄漏。您需要将realloc的结果分配给另一个指针,然后检查NULL并采取相应的行动。

使用多个realloc是否好或坏的做法取决于您要获得的内容,即性能,可维护性,清晰度等。最佳建议是:根据需要编写代码成为。然后对其进行分析性能问题?不 - >要开心。是的 - >重写代码,重点关注性能。