c - 在 stringbuffer 对象中手动分配

标签 c memory embedded malloc calloc

对于一个小型的嵌入式应用程序,我写了一些函数+结构作为字符串缓冲区(类似于 C++ 中的 std::stringstream)。

虽然这样的代码工作正常,但存在一些不太小的问题:

  • 我以前从未用 C 语言编写过手动分配 使用不断增长的内存的函数,因此恐怕还有一些问题需要解决
  • 代码分配的内存似乎比实际需要的多得多,这非常糟糕
  • 由于 valgrind 报告的警告,我已从 malloc 切换到至 calloc在代码的一个地方,它成功地删除了警告,但我不完全确定我是否真的正确使用了它

我的意思是它分配的比实际需要的多的示例(使用 56k 文件):

==23668== HEAP SUMMARY:
==23668==     in use at exit: 0 bytes in 0 blocks
==23668==   total heap usage: 49,998 allocs, 49,998 frees, 1,249,875,362 bytes allocated

...只是看起来不对...

有问题的代码在这里(太大而无法将其复制到 SO 上的 <code> 字段中):http://codepad.org/LQzphUzd

需要帮助,我很感激任何建议!

最佳答案

您增加缓冲区的方式效率很低。对于每一小段字符串,您重新分配()内存,这可能意味着分配新内存并复制“旧”内存的内容。这很慢并且会使您的堆碎片化。

更好的做法是以固定数量或固定百分比增长,即使新尺寸是旧尺寸的 1.5 倍或 2 倍。这也会浪费一些内存,但会保持堆的可用性并且不会产生太多副本。

这意味着您必须跟踪两个值:容量(分配的字节数)和长度(字符串的实际长度)。但这应该不会太难。

我会介绍一个函数“FstrBuf_Grow”来处理所有这些。您只需使用要添加的内存量调用它,FstrBuf_Grow 将通过在必要时重新分配并至少根据需要重新分配来确保容量符合要求。

...

void FstrBuf_Grow(FstringBuf *buf, size_t more)
{
    while (buf->length + more) > buf->capacity
        buf->capacity = 3 * buf->capacity / 2;
    buf->data = realloc(buf->data, buf->capacity + 1);
}            

这会将 capacity 乘以 1.5,直到 data 足够大。您可以根据需要选择不同的策略。

关于c - 在 stringbuffer 对象中手动分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7279903/

相关文章:

c - C中http header 的正则表达式

c - 这段代码的输出是什么,因为这段代码给了我一个空白输出,这怎么可能是真的?

c++ - 如何检测C中的浮点下溢

memory - 配置文件详细的 GPU 内存使用情况

c - 为 C/FFI 库调用分配对象

轻松更改嵌入式软件中的外设定时器

c - 从不改变表达式中的状态

python内存分配跟踪

r - 意外的 R 内存管理行为

linux - 自定义 Linux 图形用户界面