所以我正在完成一项任务,我无法弄清楚如何使用这个通过引用传递的2d数组。
我给的是这个
int main(){
//cap and flow initialized
maximum_flow(1000, &(cap[0][0]), &(flow[0][0]));
}
所以我想将cap的内容复制到我动态分配的另一个2d数组中,但在遇到错误后我决定打印出cap2
和capacity
中的值,我&# 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;
}
}
}
答案 0 :(得分:1)
这不是一个非常有用的答案,因为你的代码实际上没有显示所描述的问题;根据所呈现的内容,我认为cap
和cap2
在maximum_flow
函数末尾不应具有相同内容的原因并不明显。但我想提供一些背景和建议。
我将假设cap
和flow
被n
n
int
main
声明为n
,其中sizeof
{1}}在编译时是已知的。
你的教师使用这个接口的原因是将多维数组作为函数参数传递在C中是有问题的。请记住,除非它是&
或一元T
运算符的操作数,或者是一个字符串literal用于初始化declaraiton中的另一个数组, expression 类型为“{element}}的N元素数组”将被转换(“decay”)到类型为“指针”的表达式T
“,表达式的值将是数组第一个元素的地址。
所以,假设有一个像
这样的声明int cap[10][10];
int flow[10][10];
表达式 cap
和flow
将每个“衰减”到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。