これまでに20通りの方法を試したに違いありません。どうしてもこのようなエラーが発生します。
a value of type "int" cannot be used to initialize an entity of type "int (*)[30]"
つまり、このようなエラーが発生します
int(*array)[160] = malloc((sizeof *array) * 10);
そして、このようなことをしています
int** Make2DintArray(int arraySizeX, int arraySizeY) {
int** theArray;
theArray = (int**) malloc(arraySizeX*sizeof(int*));
int i;
for (i = 0; i < arraySizeX; i++)
{
theArray[i] = (int*) malloc(arraySizeY*sizeof(int));
}
return theArray;
}
これを手に入れます
"void *(size_t)" in "memory.c" at line 239 and: "int()"
int [160] [10]の2dArrayを正常に割り当てる方法の解決策はありますか
これらはどちらも問題なくコンパイルできます。最初のエラーは、同じことを宣言した関数(malloc(size_t)
など)を使用する前に_#include <stdlib.h>
_を忘れたときによく起こりますしないすることを忘れないでください。
Cには興味深いコンパイル時の動作がいくつかあります。その中には、これまでにない機能(プロトタイプ定義nor実装)を呼び出す機能があります。そのような呼び出しに遭遇すると、Cは関数が次のとおりであると想定します。
int
を返すものたとえば、関数は暗黙的に次の形式であると想定されます。
_int func();
_
多くの場合、気付かないこともあります。コンパイラからの警告を保存して、次のような影響を報告します。
_Warning: implicit declaration of `func` assumed to return `int`
_
そして、あなたがオンザボールの場合は、警告レベルをエラーとしての警告を有効にして、これをキャッチします。
しかし、そうでない場合はどうなりますか?そして、関数から返された「もの」が、実装のデータサイズによってコンテンツで表現できない場合はどうでしょうint
?たとえば、int
が32ビットで、データポインターが64ビットの場合はどうなりますか?たとえば、char *get_str()
がを含まないヘッダーファイルで宣言され、コンパイルしてプログラムとリンクする.cファイルに実装されていると仮定します。 、これは次のようになります。
_#include <stdio.h>
// Note: NO prototype for get_str
int main()
{
char *s = get_str();
printf("String: %s\n", s);
return 0;
}
_
まあ、コンパイラは吐き出して、int
と_char*
_は互換性がないことを通知します(警告の直後に_get_str
_はint
を返すと想定されます)。しかし、コンパイラにtellingさせて、何らかの方法で_char*
_を作成するとどうなるでしょうか。
_#include <stdio.h>
// Note: NO prototype for get_str
int main()
{
char *s = (char*)get_str(); // NOTE: added cast
printf("String: %s\n", s);
return 0;
}
_
これで、エラーとしての警告を有効にしないと、暗黙の宣言警告が表示されます。コードがコンパイルされます。しかし、それはrunでしょうか? sizeof(int)
!= sizeof(char*)
の場合、(32ビットと64ビット)はそうではない可能性があります。 _get_str
_から返される値は64ビットポインターですが、callerは32ビットのみが返されると想定し、それを64ビットポインターに強制します。要するに、キャストはエラーを隠し、未定義の動作のPandoraの箱を開きました。
では、これらすべてがコードとどのように関連しているのでしょうか。 _<stdlib.h>
_を含めないことにより、コンパイラはmalloc
が何であるかを認識しません。したがって、次の形式であると想定しています。
_int malloc();
_
次に、結果を_(int**)
_にキャストすることで、コンパイラーに「これから出てくるものはすべて_int**
_にする」と伝えます。リンク時に、__malloc
_が見つかり(C++のような名前のマングリングによるパラメーターシグネチャはありません)、配線され、プログラムをパーティする準備が整います。しかし、プラットフォームではint
とデータポインターは同じサイズではないので、いくつかの望ましくない結果が生じます。
sizeof(int) == sizeof(int**)
でコンパイルされた場合、通常の動作を示します。したがって、これを32ビットDebianボックスでビルドすると、すべてが問題なく見えます。 64ビットMacでビルドする教授に宿題を提出すると、クラッシュし、課題に失敗し、授業に失敗し、大学を中退し、次の10年間は、母親の地下室でサインフェルドが再走するのを見ながら猫とふれあいます。何が悪かったのかしら。痛い。
キャスティングを銀の弾丸のように扱わないでください。そうではありません。 Cでは、必要なfar人々がそれを使用するよりも少ない頻度で使用され、間違った場所で使用された場合、致命的なエラーを隠すことができます。コードでハードキャストなしにコンパイルできない箇所を見つけた場合は、もう一度見てください。あなたが絶対に、確かにキャストが正しいことだと確信していない限り、オッズはその間違っています。
この場合、malloc
が実際に何をしているのかを知るためにコンパイラーに十分な情報を提供することを怠っていたという本当のエラーを隠しました。
これを試して:
int **array;
array = malloc(rows * sizeof(int *));
for (i = 0; i < rows; i++)
array[i] = malloc(cols * sizeof(int));
// Some testing
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++)
array[i][j] = 0; // or whatever you want
}
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++)
printf("%d ", array[i][j]);
}
あなたの場合、rows = 160とcols = 10です。
このアプローチでは、2つのインデックスを使用できます。
配列を割り当てるには:
int *array = malloc(sizeof(int) * 160 * 10);
次に、次のようなコードを使用します。
array[10 * row + column] = value;
(row
は0から159までで、column
は0から9までです。)
私はレンドンの答えについてメモがあります:
彼のコードでは、Visual C++はすべての「=」操作に対して次のように言っています:error C2440: '=' : cannot convert from 'void *' to 'int **'
いくつかの変更を加えることで、私にとってはうまくいきますが、同じように機能するかどうかはわかりません。そのため、彼のコードを編集することを恐れています。代わりに、ここに私のコードを示します。これは第一印象で機能するようです。
int **a;
a = (int **)malloc(rows * sizeof(int));
for (i = 0; i < rows; i++)
{
a[i] = (int *)malloc(cols * sizeof(int));
}
for (j=0;j<rows;j++)
{
for (i=0;i<cols;i++)
{
a[i][j] = 2;
}
}
実際、私はstruct
sの代わりにカスタムint
を使用してそれを行いましたが、どちらの方法でも機能すると思います。
気にしないで、callocを使用した例を追加します
void allocate_fudging_array(int R, int C)
{
int **fudging_array = (int **) calloc(R, sizeof(int *));
for(int k = 0; k < R; k++)
{
fudging_array[k] = (int*) calloc(C, sizeof(int));
}
}
// a helper function to print the array
void print2darr(int **arr, int R, int C)
{
for(int i = 0; i < R; i++)
{
for(int j = 0; j < C; j++)
{
printf(" %d ", arr[i][j]);
}
printf("\n");
}
}