【发布时间】:2015-06-18 23:11:24
【问题描述】:
我已经做了一个简单的例子,说明如何使用 realloc 将元素添加到数组中。这将在具有更多元素的未来计划中得到扩展。
#include <stdio.h>//printf
#include <stdlib.h>//malloc, realloc
int main() {
//BEGIN REALLOCATE-ABLE ARRAY
unsigned int *array, loop_variable;
const unsigned int ORIGINAL_ARRAY_SIZE = 4, REALLOC_INDICES = 99;
array = malloc(ORIGINAL_ARRAY_SIZE*sizeof(unsigned int));
for (loop_variable = 0; loop_variable < ORIGINAL_ARRAY_SIZE; loop_variable++) {
array[loop_variable] = loop_variable;
}
//BEGIN REALLOCATION
for (loop_variable = 1; loop_variable < REALLOC_INDICES; loop_variable++) {
array = realloc(array,sizeof(unsigned int)*(ORIGINAL_ARRAY_SIZE+loop_variable));
array[ORIGINAL_ARRAY_SIZE+loop_variable-1] = 2*(ORIGINAL_ARRAY_SIZE+loop_variable-1);
printf("reallocate array[%d] = %d\n",ORIGINAL_ARRAY_SIZE+loop_variable-1,array[ORIGINAL_ARRAY_SIZE+loop_variable-1]);
}
//BEGIN PRINTING ARRAY VALUES
for (loop_variable = 0; loop_variable < ORIGINAL_ARRAY_SIZE+REALLOC_INDICES-1; loop_variable++) {
printf("array[%d] = %d\n",loop_variable,array[loop_variable]);
}
//BEGIN FREE ARRAY
free(array); array = NULL;
return 0;
}
这应该可以在任何带有 gcc 或 clang 的计算机上编译。然后我在 valgrind 上运行这个程序以确保没有内存泄漏,我得到了这个:
==10791== HEAP SUMMARY:
==10791== in use at exit: 0 bytes in 0 blocks
==10791== total heap usage: 99 allocs, 99 frees, 20,988 bytes allocated
==10791==
==10791== All heap blocks were freed -- no leaks are possible
==10791==
==10791== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==10791== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
但是,让我感到困扰的是,我使用 20,988 字节来存储 101 个元素的数组。随着数组变大,内存使用呈指数增长,而不是线性增长 4 字节/元素。
如果我正确理解 Valgrind 的输出,这个数组应该有 4*101 个元素 = 404 字节的内存大小,但 似乎使用了大约 50 倍的内存正如它应该。对于这么小的程序来说这是一个小问题,但是更有意义的程序会在这台计算机上耗尽内存。
我的问题:这个数组真的使用了 20,988 字节,还是 Valgrind 重复计算了内存?
有没有更节省内存的方法来做到这一点?我无法理解 realloc 的其他示例,尽管我已尝试尽可能密切关注它们并使这个问题与尽可能多的用户相关。
【问题讨论】:
-
Valgrind 不是将
malloc和realloc参数中的总大小报告为total heap usage,而忽略所有frees? -
你确定它是呈指数增长,而不是 O(n^2)? 20988 非常接近 4*101*101/2。
-
始终检查 (!=NULL) 从 malloc 和函数族返回的值,以确保操作成功。
-
使用 realloc() 时。将返回值分配给临时指针。测试 temp 指针是否为 NULL,(如果为 NULL,则处理错误,否则分配 array = temp 指针。否则,如果 realloc 失败,则数组中的当前指针丢失,导致内存泄漏
-
最终的 realloc 循环是:realloc( 4*(4+98) ) I.E. 400字节。既然最终大小是已知的,为什么要循环? malloc 和 realloc 是“昂贵的”,建议只有一个 malloc 的最终大小,然后是一个循环来设置分配内存的内容。
标签: c arrays memory valgrind realloc