1. ホーム
  2. c

[解決済み] 非互換なポインタタイプ

2022-02-27 11:32:27

質問

以下のシグネチャを持つ関数があります。

void box_sort(int**, int, int)

という変数があり、以下のような型になります。

int boxes[MAX_BOXES][MAX_DIMENSIONALITY+1]

関数を呼び出すとき

box_sort(boxes, a, b)

GCCは2つの警告を出します。

103.c:79: warning: passing argument 1 of ‘box_sort’ from incompatible pointer type (string where i am calling the function)
103.c:42: note: expected ‘int **’ but argument is of type ‘int (*)[11] (string where the function is defined)

質問内容は なぜ ? int x[][] と int** x (実際には int* x[]) が C 言語で同じ型でないのかどうか?

どのように解決するのですか?

数日前にこれとほぼ同じ質問があったのを知っています...しかし今は見つけられません。

答えは int[size][] (最下部の注を参照)と int** は間違いなく同じ型ではありません。あなたは int[]int* 特にこのような場合、関数に渡すと配列は最初の要素へのポインタに分解されるため、多くの場合互換性があります。しかし、2次元配列の場合、これらは全く異なる格納方法です。

2x2の配列の場合、メモリ上でどのように表示されるかを示します。

int a[2][2]:

__a[0][0]__|__a[0][1]__|__a[1][0]__|__a[1][1]__
  (int)       (int)       (int)       (int)

int **a (e.g. dynamically allocated with nested mallocs)

__a__
(int**)
  |
  v
__a[0]__|__a[1]__
  (int*)  (int*)
    |        |
    |        |
    v        ------------------>
__a[0][0]__|__a[0][1]__        __a[1][0]__|__a[1][1]__
  (int)       (int)              (int)       (int)

2つ目はこんな風に組み立てられますね。

int **a = malloc(2 * sizeof(int*));
a[0] = malloc(2 * sizeof(int));
a[1] = malloc(2 * sizeof(int));

注:他の方が指摘されているように int[][] は実数型ではなく、どちらか一方のサイズしか指定できない。しかし、ここでの問題の核心は、2次元配列とダブルポインタが同じものであるかどうかということです。