![](/img/trans.png)
[英]Dynamically allocating two dimensional string array and passing it as parameter to functions
[英]Functions for dynamically allocating an array in C -- Any difference between the two?
假设您在 C 中有一个函数,它接受二维数组的维数(为简单起见,比如说一个正方形 nxn 数组),动态分配数组,然后返回它。
我知道在这里分配内存一开始可能被认为是有些不好的做法,因为它需要在其他地方释放,但假设这不是一个大问题。 我想知道上述功能的这两种变体是否有任何优点/缺点:
变体 1 - 在函数中本地定义 int** 变量,分配/返回数组:
int **create_array(int n) {
// define array pointer, allocate array...
int **a_ = (int**)calloc(n,sizeof(int*));
for (int i = 0; i < n; i++)
a_[i] = (int*)calloc(n,sizeof(int));
return a_;
}
int main() {
int n = 3;
int **array2d = create_array(n)
printf("First element: %d%c",array2d[0][0],'\n');
// do stuff... etc...
}
变体 2 - 向函数添加 in-out int** 参数,分配/返回数组:
int **create_array_2(int **a_, int n) {
// allocate array...
a_ = (int**)calloc(n,sizeof(int*));
for (int i = 0; i < n; i++)
a_[i] = (int*)calloc(n,sizeof(int));
return a_;
}
int main() {
int n = 3;
int **array2d;
array2d = create_array_2(array2d,n);
printf("First element: %d%c",array2d[0][0],'\n');
// do other stuff... etc...
}
显然,它们返回相同的结果并完成相同的任务,但是否认为一种比另一种更安全/更有效/更好的做法? 在我看来,第二个变体只是让事情看起来有点多余,但我很好奇两者之间是否有任何真正的区别以及调用它们时堆栈/堆上会发生什么。 希望这不是一个愚蠢的问题; 这只是我一直很好奇的事情。 如果有人有见解可以分享,我将不胜感激。
我可能会尽量避免多次调用malloc
和free
,所以这种方法就是我要做的:
示例 1:
#include <stdio.h>
#include <stdlib.h>
int *foo(size_t row, size_t col);
int main(void){
int *arr;
unsigned int row, col, k;
printf("Give the ROW: ");
if ( scanf("%u",&row) != 1){
printf("Error, scanf ROW\n");
exit(1);
}
printf("Give the COL: ");
if ( scanf("%u",&col) != 1){
printf("Error, scanf COL\n");
exit(2);
}
arr = foo(row, col);
for (k = 0 ; k < (row * col) ; k++){
printf("%d ",arr[k]);
}
free(arr);
}
int *foo(size_t row, size_t col){
unsigned int i, j;
int *arr = malloc(sizeof *arr * row * col);
int l = 0;
if(arr == NULL){
printf("Error, malloc\n");
exit(3);
}
for ( i = 0; i < row ; i++){
for ( j = 0 ; j < col ; j++){
arr[i * col + j] = l;
l++;
}
}
return arr;
}
输出:
Give the ROW: 6
Give the COL: 3
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
示例 2(如果您使用的是标准 C):
#include <stdio.h>
#include <stdlib.h>
int (*foo(size_t row, size_t col))[];
int main(void){
size_t row, col;
printf("Give the ROW: ");
if ( scanf("%zu",&row) != 1){
printf("Error, scanf ROW\n");
exit(1);
}
printf("Give the COL: ");
if ( scanf("%zu",&col) != 1){
printf("Error, scanf COL\n");
exit(2);
}
int (*arr)[col] = foo(row, col);
for ( size_t i = 0; i < row; i++){
for( size_t j = 0; j < col; j++){
printf("%d ",*(*(arr+i)+j));
}
}
free(arr);
}
int (*foo(size_t row, size_t col))[]{
int (*arr)[col] = malloc(row * col * sizeof(int));
int l=0;
if (arr == NULL){
printf("Error, malloc\n");
exit(3);
}
for ( size_t i = 0; i < row; i++){
for( size_t j = 0; j < col; j++){
*(*(arr+i)+j) = l;
l++;
}
}
return arr;
}
输出:
Give the ROW: 6
Give the COL: 3
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
这里的重点是在两个例子中malloc
和free
的调用只发生一次
IMO,在这两者中,您最好简单地返回值。 这样你和来电者之间就有了一道纯粹而坚固的墙。
“给我一些东西!”
“好的,这里有一些东西。”
另一方面,为了实际分配一个固定大小的数组,为什么要使用指针呢? 为什么不声明您的返回类型以便可转换为一个大小的数组?
int (*p2a)[15] = (int(*)[15])create_array_2(15, 15);
然后你会calloc(15*15,sizeof(int))
并完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.