c - 在 C 中存储未知迭代次数的 while 循环的结果

标签 c arrays pointers while-loop malloc

我有一个 while 循环,在未知次数的迭代后满足 if(condition){break;} 时退出。在 while 循环中,调用了一个函数,该函数将在每次迭代时返回一个可变大小的数组。我知道在 python 中我可以将数组彼此附加,最后我会得到一个大小可变的数组。在 C 中执行此操作的正确方法是什么?

这是我的代码的相关部分(我知道它不是 MWE,缺少很多部分,但我希望它仍然可以理解):

int find_zeros(double *kappa, double *zeros){

    // reset the counter "z"
    int z = 0;

    // do some calculations and compute the zeros
    // update the value of z for every zero found

    // "zeros" now contains "z" elements
    return z;
}

double *foo(){

    // allocate memory for the "zeros" array (I know that N>z)
    double *zeros = (double *) malloc (sizeof(double) *N);

    // variable to count the elements of the "zeros" array
    int z;

    while (1){

        z = find_zeros(kappa, zeros);

        // if no zeros where found, exit the while loop
        if (z==0){ break; }

        // now we know how many zeros we have (z has been updated 
        // by find_zeros()), so we can reallocate the memory
        zeros = (double *) realloc(zeros, sizeof(double) *z);

        // append the zeros somewhere (how?!)
        // in python I would do: zeros_list.append(zeros)
    }

    // free the memory for the "zeros" array
    free(zeros);

    // return all the zeros found 
    // in python I would do: return zeros_list
}

int main(){

    double *zeros_list = what?? 
    // how do I allocate memory of a thing that I don't
    // know how big it is going to be?

    zeros_list = foo();
}

最佳答案

您需要将零存储在 foo 中,独立于 find_zeros 返回的值,就像在 Python 中一样,您会有单独的变量 zeros_listzeros

Python 的 list.append 方法分两步实现:首先使用 realloc 将数组重新分配到新的容量(你已经有了那部分),然后是新的值被分配给新的可用空间。由于您正在创建一个数组数组,因此您还需要使用 memcpy() 将值从它们的临时位置复制到新位置。例如(未经测试,没有 MWE):

struct floatvec {
    double *values;
    int length;
}

struct floatvec *foo(int *howmany) {
    struct floatvec *zeros_list = NULL;
    int zeros_cnt = 0;
    static double zeros[N];

    while (1) {
        int z = find_zeros(kappa, zeros);
        if (z == 0)
            break;

        struct floatvec new = {
            .values = malloc(z * sizeof(double)),
            .length = z
        };
        if (!new.values)
            return NULL;
        memcpy(new.values, zeros, sizeof(double) * z);

        zeros_list = realloc(zeros_list, sizeof(struct floatvec) * (zeros_cnt + 1));
        if (!zeros_list)
            return NULL;
        zeros_list[zeros_cnt++] = new;
    }

    *howmany = zeros_cnt;
    return zeros_list;
}

使用示例:

int cnt;
struct floatvec *all_zeros = foo(&cnt);
for (int i = 0; i < cnt; i++) {
    struct floatvec *curr = all_zeros[i];
    for (int j = 0; j < curr->length; j++)
        printf("%lf\n", curr->values[j]);
}

一些不相关的注释:

  • 不要转换 malloc and realloc 的结果.
  • 检查 malloc 是否返回 NULL 并中止您的程序或将错误返回给调用者。

编辑:更新答案以匹配编辑后的问题。

关于c - 在 C 中存储未知迭代次数的 while 循环的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58487038/

相关文章:

c++ - 创建具有给定格式的 C++ 字符串

arrays - swift 3 : Check for item in an array

arrays - 为什么int ** x与int x [] []不同?

java - 为什么线程创建的数组会返回空指针异常?

pointers - 如何传递函数引用而不是函数本身?

c - 读取目录中具有相同扩展名的文件并统计其行数

c++ - 使用 SIMD 范例在 256 位 vector 上应用给定函数

c - c中指向堆栈位置的指针

c - 好的老初学者 killer : Pointers

指向全局变量 : Different Pointers 的 C 指针