使用引用C传递的2d数组时遇到问题

时间:2016-05-23 13:34:59

标签: c arrays multidimensional-array

所以我正在完成一项任务,我无法弄清楚如何使用这个通过引用传递的2d数组。

我给的是这个

int main(){
//cap and flow initialized 
maximum_flow(1000, &(cap[0][0]), &(flow[0][0]));

}

所以我想将cap的内容复制到我动态分配的另一个2d数组中,但在遇到错误后我决定打印出cap2capacity中的值,我&# 39;我没有收回我应该做的所有价值观。

void maximum_flow(int n, int *capacity, int *flow){
    int **cap2;
    cap2 = (int**) malloc(sizeof(int *)*n);
    for (i = 0; i < n; i++)
    {
      cap2[i] = (int*) malloc(sizeof(int)*n);
    }

    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {   
          cap2[i][j] = (*(capacity + i*n + j));
          (*(flow + i*n + j)) = 0;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

这不是一个非常有用的答案,因为你的代码实际上没有显示所描述的问题;根据所呈现的内容,我认为capcap2maximum_flow函数末尾不应具有相同内容的原因并不明显。但我想提供一些背景和建议。

我将假设capflown n int main声明为n,其中sizeof {1}}在编译时是已知的。

你的教师使用这个接口的原因是将多维数组作为函数参数传递在C中是有问题的。请记住,除非它是&或一元T运算符的操作数,或者是一个字符串literal用于初始化declaraiton中的另一个数组, expression 类型为“{element}}的N元素数组”将被转换(“decay”)到类型为“指针”的表达式T“,表达式的值将是数组第一个元素的地址。

所以,假设有一个像

这样的声明
int cap[10][10];
int flow[10][10];
表达式 capflow将每个“衰减”到int (*)[10]类型(指向int的10个元素数组的指针)。因此,如果您将函数调用编写为

maximum_flow( 1000, cap, flow );

然后函数定义必须写成

void maximum_flow( int n, int (*cap)[10], int (*flow)[10] ) { ... }

void maximum_flow( int n, int cap[][10], int flow[][10] ) { ... }

在函数参数声明的上下文中,T a[][N]T (*a)[N]表示同样的事情。

外部维度的大小要在数组指针声明中指定,问题是指向10个元素数组的指针是不同的,不兼容从指向any-value-other-than-10-element数组的指针输入;因此,maximum_flow只能用于N x 10元素数组,限制了它的用途。解决此问题的一种方法是让函数接收指向第一个元素的显式指针,并将该指针视为大小为N * M的一维数组。

简而言之,因为您将输入参数视为一维数组,所以最好将cap2创建为一维数组:

int *cap2 = malloc( sizeof *cap2 * n * n );
...
cap2[i * n + j] = capacity[i * n + j]; // use array subscript notation instead
flow[i * n + j] = 0;                   // of explicit dereferences

根据您发布的代码,不清楚maximum_flow应该做什么,也不清楚为什么需要cap2。另请注意,在某些时候,您需要free分配给cap2的内存,否则您会发生内存泄漏。

如果您使用的是C99或更高版本的编译器,则应该能够使用可变长度数组而不是malloc

int cap2[n * n]; // or int cap2[n][n], but like I said above, if you're 
                 // treating your inputs as 1D arrays, you should also treat
                 // cap2 as a 1D array. 

VLA的优点是你不需要在编译时知道大小,并且它被视为任何其他auto变量,这意味着当函数退出时它将释放它的内存。

VLA的缺点是你不能将它用作的任何东西,而是一个局部变量;您不能将VLA作为结构或联合成员,也不能声明一个static或文件范围。你也不能明确初始化VLA。