main.c:警告:传递参数‘’;来自不兼容的指针类型

main.c:警告:传递参数‘’;来自不兼容的指针类型,c,pointers,dynamic,malloc,C,Pointers,Dynamic,Malloc,我试图通过参数传递并返回一个二维动态数组,但是它总是显示我在问题中提到的警告。我知道数组参数有问题,但我在任何一本书或一个网站上都找不到如何正确传递一个维度发生变化的数组。我已经阅读了与我类似的关于警告的问题,主要是关于在指针中添加&,我没有在我的指针中添加 #include <stdio.h> #include <stdlib.h> void fun(int m, int n, int (*arr)[n]); int main(void) { int i,

我试图通过参数传递并返回一个二维动态数组,但是它总是显示我在问题中提到的警告。我知道数组参数有问题,但我在任何一本书或一个网站上都找不到如何正确传递一个维度发生变化的数组。我已经阅读了与我类似的关于警告的问题,主要是关于在指针中添加
&
,我没有在我的指针中添加

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

void fun(int m, int n, int (*arr)[n]);

int main(void) {
    int i, j, m, n, **arr;
    printf("Enter the dimensions m, n\n");
    scanf("%d %d", &m, &n);
    arr = (int **)malloc(m * sizeof(int *));
    for (i = 0; i < m; i++) {
        arr[i] = (int *)malloc(n * sizeof(int));
    }
    fun(m, n, *arr);
    printf("\n\n");
    for (i = 0; i < m; i++) {
        for (j = 0; j < n; j++) {
            printf("%5d", arr[i][j]);
        }
        printf("\n");
    }
    if (arr == NULL) {
        exit(1);
    } else
    if (arr != NULL) {
        free(arr);
    }
    return 0;
}

void fun(int m, int n, int (*arr)[n]) {
    int i, j, k = 0;
    for (i = 0; i < m; i++) {
        for (j = 0; j < n; j++) {
            k = k + 1;
            arr[i][j] = k;
        }
    }
}
#包括
#包括
无效乐趣(整数m,整数n,整数(*arr)[n]);
内部主(空){
整数i,j,m,n,**arr;
printf(“输入尺寸m,n\n”);
scanf(“%d%d”,&m,&n);
arr=(int**)malloc(m*sizeof(int*);
对于(i=0;i
main
中,
arr
是指向整数指针的指针,您可以使用嵌套内存分配填充它,因为它涉及两个级别的指针。
arr[i]
可以被分割,每个可以包含不同数量的条目,这使得
arr
成为一个“不规则”数组

函数的参数是指向
n
整数数组的指针。这里,
arr
的条目在内存中是连续的,因此
arr[0]
arr[1]
之间的间隔是
sizeof(int[n])
字节

这些是不同的类型,编译器会告诉您这一点。挑一个

A您可以坚持指针对指针的方法。然后,您的函数签名必须与
main
中的定义匹配:

void fun(int m, int n, int **arr) ...
在这种情况下,您还必须在
free(arr)
之前的末尾
all
arr[i]

B或者,您可以保留curret函数并使用单个分配创建连续数组:

int (*arr)[n] = malloc(m * sizeof(*arr));
然后直接将其传递给函数,而不取消引用:

fun(m, n, arr);

最后,只需
free(arr)
您将指针传递给int(即*arr),但您已经声明了一个函数,该函数将获取指向
n
整数数组的指针

因此,只需进行以下更改:

void fun(int m, int n, int **arr); // also change where function definition begins
fun(m, n, arr);
顺便说一下,释放内存是不完整的

for (i=0; i<m; i++)
  free(arr[i]); // first free individual array elements
free(arr);

for(i=0;i
fun
被定义为接收指向可变大小数组或
n
int
的指针。这是一些C编译器可能不支持的C99特定语法。您也可以使用更简单、更可读的原型来定义
fun
,该原型实际上是等效的:

void fun(int m, int n, int arr[m][n]);
也相当于这个:

void fun(int m, int n, int arr[][n]);
问题是您分配了一种非常不同类型的对象:一个由
m
指针组成的数组,指向
n
int
数组。您应该分配一个由
m
数组组成的
n
int
可变大小数组,并将其地址存储到具有适当类型的指针:

int (*arr)[n] = malloc(m * sizeof(*arr));
或者将其定义为具有自动存储的2D可变大小阵列:

int arr[m][n];
如果分配了
malloc()
,您将使用

free(arr);
以下是修改后的版本:

#包括
#包括
虚空乐趣(int m,int n,int arr[m][n]);
内部主(空){
int i,j,m,n;
printf(“输入尺寸m,n\n”);

如果(scanf(“%d%d”,&m,&n)!=2 | | m,我看不到您在
gcc 7.4.0
和命令
gcc-Wall filename.c-o testfile
中提到的警告,因此可能提及编译器版本等会有所帮助;
gcc
警告我,您正在传递的是
*arr
,而不是
arr
fun()
显然想要一个指向数组的指针,也就是说,
int**
——这是您分配的;但是,看起来您正在传递一个
int*
int(*arr)[n]
声明指向
n
大小数组的指针,您需要
int**
。两个一般性建议:(a)保持简单,必要时使用
int*
int**
等。(b)使用数组时避免使用双指针;相反,分配扁平内存块(除非它们非常大)并执行指针算术:
p[i*n+j]=value
style;这可能会使您的生活稍微简单一些,编写代码也更容易read@ch3055:您可以通过单击分数下方的灰色复选标记来接受其中一个答案。谢谢!我有空(arr[I])之前,它显示了另一个警告,并通过删除它进行了修复。但int**毕竟是问题所在。谢谢!这个和其他答案真的很有帮助。
int arr[m][n];
free(arr);