繁体   English   中英

使用malloc和realloc进行动态存储的最佳方法

[英]optimal way of using malloc and realloc for dynamic storing

我试图弄清楚使用malloc和realloc从用户那里收集未知数量的字符,存储它们以及仅在结束时打印它们的最佳方法。

我认为调用realloc太多次都不会那么聪明。 所以相反,我每次都分配一定量的空间,让我们说sizeof char * 100并在文件的末尾,我使用realloc来精确地拟合整个事物的大小。

你觉得怎么样?这是一个好方法吗? 你会走另一条路吗?

请注意,我无意使用链表,getchar(),putchar()。 仅使用malloc和realloc是必须的。

如果重新分配以适应所需的确切数据量,那么您将优化内存消耗。 这可能会导致代码变慢,因为1)您获得额外的realloc调用; 2)您可能无法分配适合CPU对齐和数据缓存的数量。 可能这也会导致堆分段问题,因为重复的reallocs,在这种情况下它实际上可能浪费内存。

通常很难回答什么是“最佳”,但下面的方法相当常见,因为它是降低realloc调用的执​​行速度和降低内存使用之间的良好折衷:

您分配一个段,然后跟踪该段的用户数据量。 分配size_t mempool_size = n * _Alignof(int);是个好主意size_t mempool_size = n * _Alignof(int); 使用可被8整除的n也可能是明智的。

每次在此段中耗尽可用内存时,都会重新分配到mempool_size*2个字节。 这样你每次都可以将可用内存增加一倍。

我认为调用realloc太多次都不会那么聪明。

你是怎么想出来的? 因为真正了解的唯一方法是衡量绩效。

您的策略可能需要根据您从用户读取数据的方式而有所不同。 如果您使用的是getchar()那么每次读取一个字符时,您可能不希望使用realloc()将缓冲区大小增加一个char。 但是,即使在这些情况下,一个好的realloc()也会比你想象的低效率低得多。 我认为,glibc实际上为了响应malloc()而给出的最小块大小是16个字节。 因此,从0到16个字符并且每次重新分配不涉及任何复制。 类似地,对于较大的重新分配,可能不需要分配新块,可以使现有块更大。 不要忘记,即使是最慢的, realloc()也会比人们输入的更快。

大多数人不会采取这种策略。 输入的内容可以通过管道传输,因此人们不能快速打字的论点不一定有效。 通常,您会介绍容量的概念。 您分配具有特定容量的缓冲区,当它满了时,您可以通过添加特定大小的新块来增加其容量(使用realloc() )。 初始大小和重新分配大小可以通过各种方式进行调整。 如果您正在读取用户输入,则可能需要较小的值,例如256个字节,如果您正在从磁盘或网络上读取文件,则可能需要更大的值,例如4Kb或更大。

增量大小甚至不需要是常量,您可以选择将每个所需重新分配的大小加倍。 这是一些编程库使用的策略。 例如,我相信哈希表的Java实现使用它,因此可能是数组的Cocoa实现。

事先不可能知道在任何特定情况下最佳策略是什么。 我会选择一些感觉正确的东西然后,如果应用程序有性能问题,我会做测试来调整它。 您的代码不一定是最快的,但速度足够快。

然而,我绝对不会做的一件事是在内置分配器的顶部覆盖一个家庭滚动内存算法。 如果你发现自己维护了一个你没有使用的块列表而不是释放它们,那么你做错了。 这就是让OpenSSL陷入困境的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM