Realloc使用太多内存

时间:2015-04-13 15:07:57

标签: c arrays memory valgrind realloc

我已经做了一个简单的工作示例,说明如何使用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的其他例子,尽管我尽可能地密切关注它们,并使这个问题与尽可能多的用户相关。

2 个答案:

答案 0 :(得分:5)

==10791==     in use at exit: 0 bytes in 0 blocks
==10791==   total heap usage: 99 allocs, 99 frees, 20,988 bytes allocated
  

这个数组真的使用了20,988字节

不,它使用的是0字节。

“已分配”显然意味着“永远分配”,包括已被释放的字节,因为“仍然分配”的内存量为零(另一行告诉你)。

答案 1 :(得分:0)

感谢用户Pascal Cuoq,答案是Valgrind将为每个分配总结内存分配。这就是为什么我感到困惑,并认为realloc使用了太多内存。

我认为如果你想找到数组的大小,你可以注释掉

的行
free(array); array = NULL;

故意引入内存错误,Valgrind将输出

==11699== LEAK SUMMARY:
==11699==    definitely lost: 408 bytes in 1 blocks
==11699==    indirectly lost: 0 bytes in 0 blocks
==11699==      possibly lost: 0 bytes in 0 blocks
==11699==    still reachable: 0 bytes in 0 blocks
==11699==         suppressed: 0 bytes in 0 blocks
==11699== 
==11699== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==11699== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

,它为您提供最后一次迭代时数组的真实大小。可能有更好的方法来做到这一点,但我的意思是。

我在此处添加了其他用户建议的改进。我很难找到搜索引擎上realloc的好的,最小的工作示例,以及将来在搜索引擎上找到这个的人使用,这是一个很好的基本的最小工作示例,但可能不是最好的,如何使用在C中重新分配:

#include <stdio.h>//include printf function
#include <stdlib.h>//include malloc, realloc functions

int main() {
/*BEGIN REALLOCATE-ABLE ARRAY*/
    unsigned int *array, loop_variable;
    const unsigned int ORIGINAL_ARRAY_SIZE = 4, REALLOC_INDICES = 99999;
    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));
        if (array == NULL) {
            printf("Array variable %d failed to reallocate :,-(\n",loop_variable);
            exit(EXIT_FAILURE);
        }
        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;
}