首页 > 解决方案 > 函数在 C 中分配和修改许多(多个)数组

问题描述

C函数可以通过传递引用的错觉(如Ely解释的地址传递值)来修改多个变量,例如

#include <stdio.h>

void function(int *pa, int *pb) {
    *pa *= *pa;
    *pb *= *pb;
}

int main(void) {
    int a = 1, b = 2;
    function(&a, &b);
    printf("a = %d\nb = %d\n", a, b);
    return 0;
}

哪个输出

a = 1
b = 4

还可以通过返回指向数组的指针来修改整个变量范围,例如

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

int *function(int *ptr_size) {
    int n = 6;  // arbitrary ptr_size
    int *array = (int *)malloc(n * sizeof(int));
    for (int i = 0; i < n; ++i)
        array[i] = i * i;
    //
    *ptr_size = n;
    return array;
}

int main(void) {
    int size = 0;
    int *array = function(&size);
    printf("size = %d\n", size);
    for (int i = 0; i < size; ++i)
        printf("array[%d] = %d\n", i, array[i]);
    free(array);
    array = NULL;
    return 0;
}

输出:

size = 6
array[0] = 0
array[1] = 1
array[2] = 4
array[3] = 9
array[4] = 16
array[5] = 25

但是,如果我想要一个修改多个(动态分配的)数组的函数呢?
我试过这个

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

void function(int *array, int *ptr_asize, int *brray, int *ptr_bsize) {
    int size = 6;
    array = (int *)malloc(size * sizeof(int));
    brray = (int *)malloc(size * sizeof(int));
    for (int i = 0; i < size; ++i) {
        array[i] = i * i;
        brray[i] = i * i * i;
    }
    *ptr_asize = size;
    *ptr_bsize = size;
}

int main(void) {
    int asize, bsize;
    int *array, *brray;
    function(array, &asize, brray, &bsize);
    // array
    printf("asize = %d\n", asize);
    for (int i = 0; i < asize; ++i)
        printf("array[%d] = %d\n", i, array[i]);
    free(array);
    array = NULL;
    // brray
    printf("bsize = %d\n", bsize);
    for (int i = 0; i < bsize; ++i)
        printf("brray[%d] = %d\n", i, brray[i]);
    free(brray);
    brray = NULL;
    //
    return 0;
}

但它会导致分段错误
这并不奇怪,如何知道分配了main多少内存?arraybrray

所以我的问题是:C 语言中,一个函数是否有可能分配和修改多个数组,而这些更改仍然存在main

PS:一个解决方案是分配一个abrray包含arraybrrayint **function(...) { ... return abrray; })的新的,但我想知道一个函数是否可以修改两个(或更多)数组,并且更改保留在main.

标签: arrayscpointersdynamic-memory-allocation

解决方案


将指针传递给指针,如下所示:

void func(int** array, int** brray, size_t size_a, size_t size_b) {
*array = malloc(size_a * sizeof(int));
*brray = malloc(size_b * sizeof(int));
}

像这样称呼它:

int *arr, *brr;
func(&arr, &brr, 2, 5);

推荐阅读