【问题标题】:C dynamically growing array with mallocC使用malloc动态增长数组
【发布时间】:2019-03-31 21:02:23
【问题描述】:

我尝试创建使用 realloc 进行的动态增长数组。我有下面的例子,但我不明白这段代码是如何使用 malloc 工作的。

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int cnt = 0;
    double *numbers = NULL;
    double newnum;
    while (scanf("%lf", &newnum) == 1 && newnum != -1) {
        double *newarr = (double*) malloc(sizeof(double) * (cnt+1)); 
        for (int i = 0; i < cnt; ++i)
            newarr[i] = numbers[i]; 
        free(numbers); 
        numbers = newarr;
        numbers[cnt] = newarr; 
        ++cnt;
    }

    for (int i = cnt-1; i >= 0; --i) {
        printf("%f\n", numbers[i]);
    }

    free(numbers);

    return 0;
}

【问题讨论】:

标签: c


【解决方案1】:

realloc()malloc()memcpy()free() 功能相同(*)

代码中的循环有效地替换了memcpy()

        // memcpy(newarr, numbers, cnt * sizeof *newarr);
        for (int i = 0; i < cnt; ++i)
            newarr[i] = numbers[i]; 

(*) realloc() 可能足够聪明,可以避开memcpy()free() 并重用内存。


如何在我的代码中实现这一点?

它有助于将指针和总/使用的元素封装在一个结构中。

#include <stdio.h>
#include <stdlib.h>

struct DynArray {
    double *data;
    size_t m; // total
    size_t n; // used
};

void growarray(struct DynArray *x) {
    size_t newsize = x->m * 13 / 8 + 1; // use phi aproximation 13/8
    double *newarr = realloc(x->data, newsize * sizeof *x->data);
    if (!newarr) exit(EXIT_FAILURE);
    fprintf(stderr, "INFO: realloc'ed with %d elements.\n", (int)newsize);
    x->data = newarr;
    x->m = newsize;
}

int main(void) {
    struct DynArray numbers = { 0 };
    double newnum;
    while (scanf("%lf", &newnum) == 1 && newnum != -1) {
        if (numbers.n == numbers.m) growarray(&numbers);
        numbers.data[numbers.n] = newnum;
        numbers.n++;
    }

    for (int i = numbers.n - 1; i >= 0; --i) {
        printf("%f\n", numbers.data[i]);
    }

    free(numbers.data);

    return 0;
}

See code running on ideoneprevious version without growarray functionprevious version with cnt

【讨论】:

  • 我明白了。使用 realloc 似乎更好。
  • 还意识到内存分配是一项缓慢的操作,当您确实需要更多空间时,您应该使用 x2 或更好的黄金比例分别将数组大小加倍或 ~x1.618,并且不是每一次迭代......
  • @EmilBədrəddinli:很好看! cnt 是原始代码的遗留物。它被numbers.n 取代。删除是安全的,我已经编辑了我的答案。
  • 解释清楚。谢谢
猜你喜欢
  • 2020-04-13
  • 1970-01-01
  • 2021-12-29
  • 2021-03-27
  • 2012-11-04
  • 2020-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多