C malloc用例 - realloc与预计算

时间:2014-08-07 19:25:30

标签: c arrays malloc

我想从另一个数据结构在堆上创建一个结构数组。假设要遍历N个元素,并且(N-x)指针(computed_elements)将被添加到数组中。

我的天真策略是在堆栈上创建一个数组(temp_array)大小N并遍历数据结构,跟踪需要添加到数组中的元素数量,并在遇到它们时将它们添加到temp_array中。完成后,我使用malloc(computed_elements)并使用temp_array填充此数组。

这不是最理想的,因为第二个循环是不必要的。但是,我正在权衡这个与每次迭代不断重新分配内存的权衡。一些粗略的代码澄清:

void *temp_array[N];
int count = 0;
for (int i = 0; i < N; i++) {
  if (check(arr[i])) {
    temp_array[count] = arr[i];
    count++;
  }
}

void *results = malloc(count * sizeof(MyStruct));
for (int i = 0; i < count; i++) {
  results[i] = temp_array[i];
}

return results;

我们将不胜感激。

3 个答案:

答案 0 :(得分:3)

一个常见的策略是尝试估计您需要的元素数量(不是近似估计,更多是&#34;按... ...#34;类型估计的顺序) 。 Malloc那段记忆,当你得到&#34;关闭&#34;到了那个限度(&#34;关闭&#34;也正在进行解释),重新分配更多。就个人而言,当我接近填充它时,我通常会将数组加倍。

<强> - 编辑 -

这是&#34;十分钟版本&#34;。 (我确保它构建并且不会发生段错误)

显然我省略了检查malloc / realloc成功,归零内存等事情......

#include <stdlib.h>
#include <stdbool.h>
#include <string.h>     /* for the "malloc only version" (see below) */

/* Assume 500 elements estimated*/
#define ESTIMATED_NUMBER_OF_RECORDS   500

/* "MAX" number of elements that the original question seems to be bound by */
#define N   10000

/* Included only to allow for test compilation */
typedef struct
{
    int foo;
    int bar;
} MyStruct;

/* Included only to allow for test compilation */
MyStruct arr[N] = { 0 };

/* Included only to allow for test compilation */
bool check(MyStruct valueToCheck)
{
    bool baz = true;
    /* ... */
    return baz;
}

int main (int argc, char** argv)
{
    int idx = 0;
    int actualRecordCount = 0;
    int allocatedSize = 0;
    MyStruct *tempPointer = NULL;

    MyStruct *results = malloc(ESTIMATED_NUMBER_OF_RECORDS * sizeof(MyStruct));
    allocatedSize = ESTIMATED_NUMBER_OF_RECORDS;

    for (idx = 0; idx < N; idx++)
    {
        /* Ensure that we're not about to walk off the current array */
        if (actualRecordCount == (allocatedSize))
        {
            allocatedSize *= 2;

            /* "malloc only version"
             * If you want to avoid realloc and just malloc everything...
             */
            /*
            tempPointer = malloc(allocatedSize);
            memcpy(tempPointer, results, allocatedSize);
            free(results);
            results = tempPointer;
            */

            /* Using realloc... */
            tempPointer = realloc(results, allocatedSize);
            results = tempPointer;
        }

        /* Check validity or original array element */
        if (check(arr[idx]))
        {
            results[actualRecordCount] = arr[idx];
            actualRecordCount++;
        }
    }

    if (results != NULL)
    {
        free(results);
    }

    return 0;
}

答案 1 :(得分:0)

一种可能性是大小为N的malloc,然后运行循环,然后重新分配大小N-x。内存碎片可能导致小x。

答案 2 :(得分:0)

最佳可重用代码通常是可扩展。除非有义务使用小尺寸,否则假设代码将在后续应用程序中增长,并且对于大N需要合理有效。您确实希望重用良好的代码。

根据需要,

realloc()数组大约4倍。数组也可能缩小 - 不需要放置一个膨胀阵列。我使用了4倍的间隔1,4,16,64 ......并且收缩间隔为2,8,32,128 ......通过相互间隔生长/收缩间隔,它避免了大量的N应该在一段时间内动摇。

即使在很小的方面,例如使用size_tint。当然,对于像1000这样的大小,没有区别,但是重复使用代码后,应用程序可能会突破限制:size_t对于数组索引更好。

void *temp_array[N];
for (int i = 0; i < N; i++) {

void *temp_array[N];
for (size_t i = 0; i < N; i++) {
相关问题