【问题标题】:main.c: warning: passing argument of ‘’ from incompatible pointer typemain.c:警告:从不兼容的指针类型传递“”参数
【发布时间】:2020-07-29 06:39:39
【问题描述】:

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

#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;
        }
    }
}

【问题讨论】:

  • 我看不到你用gcc 7.4.0 和命令gcc -Wall filename.c -o testfile 提到的警告,所以可能提到编译器版本等可能会有所帮助;不过,gcc 警告我,您传递的是 *arr 而不是 arrfun() 显然想要 指向数组的指针,即 int ** - 这是你分配什么;但看起来你正在传递一个int *
  • int (*arr)[n] 声明指向n 大小的数组的指针,您需要int **
  • 两个一般性建议:(a) 保持简单,并在需要时使用int*int** 等。 (b) 使用数组时避免使用双指针;相反,分配平坦的内存块(除非它们 真的 大)并进行指针运算:p[i*n+j] = value 风格;这可能会让你的生活更简单,代码更容易阅读
  • @ch3055:您可以通过单击分数下方的灰色复选标记来接受其中一个答案。

标签: c pointers dynamic malloc


【解决方案1】:
int **arr;

main 中,arr 是一个指向整数指针的指针,并且您使用嵌套的内存分配填充它,因为涉及到两个级别的指针。 arr[i] 可以分段,每个可以包含不同数量的条目,使 arr 成为一个“参差不齐”的数组。

int (*arr)[n]

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

这些是不同的类型,编译器会告诉你。选择一个。

A 您可以坚持使用指针对指针的方法。那么你的函数签名必须匹配main中的定义:

void fun(int m, int n, int **arr) ...

在这种情况下,您还必须在最后 free all arr[i],在 free(arr) 之前。

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

int (*arr)[n] = malloc(m * sizeof(*arr));

然后直接将其传递给您的函数而不取消引用它:

fun(m, n, arr);

最后,只需free(arr)

【讨论】:

  • 谢谢!我之前有 free(arr[i]) 但它显示另一个警告,并通过删除它来修复它。但 int ** 终究是问题所在。
【解决方案2】:

您正在传递指向 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);

【讨论】:

  • 谢谢!这个和其他答案真的很有帮助。
【解决方案3】:

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 的数组指向nint 的数组。您应该分配一个由m 可变大小的n int 数组组成的数组,并将其地址存储到具有适当类型的指针中:

int (*arr)[n] = malloc(m * sizeof(*arr));

或者只是将其定义为具有自动存储功能的 2D 可变大小数组:

int arr[m][n];

如果使用malloc() 分配,您将使用释放对象

free(arr);

这是修改后的版本:

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

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

int main(void) {
    int i, j, m, n;

    printf("Enter the dimensions m, n\n");
    if (scanf("%d %d", &m, &n) != 2 || m <= 0 || n <= 0)
        return 1;

    int (*arr)[n] = malloc(m * sizeof(*arr));
    if (arr == NULL)
        return 1;

    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");
    }
    free(arr);
    return 0;
}

void fun(int m, int n, int arr[m][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;
        }
    }
}

【讨论】:

    猜你喜欢
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多