-1

以下のようなCの関数で配列を作成できないのはなぜですか?

int **image;
int height, weight;//initialized in a method not shown

void generateMatrices()
{
    image = (int **)malloc(sizeof(int*) * height);
    if(image == NULL)
    {
        fprintf(stderr, "Image matrix could not be made\n");
        exit(-1);
    }
    int y;
    for(y = 0; y < height; y++)
    {
        image[y] = (int *)malloc(sizeof(int) * width);
        if(image[y] == NULL)
        {
            fprintf(stderr, "Image matrix row %d could not be made\n", y);
            exit(-1);
        }
    }
}

int main(int argc, char* argv[])
{
    generateMatrices();
    image[height-2][width-2] = 90;//Fails here
    return 0;
}

まず、この不明確な質問をしてしまったことをお詫び申し上げます。明確にするために、私はこれらの行列を作成する方法を知っています、そして実際、それは機能します。ただし、そのコードはすべて元々メインステートメントに含まれていたため、さまざまなメソッドにコードを配置してコードをリファクタリングしたいと思いました。これらのメソッドの1つは、generateMatrices()というタイトルです。何らかの理由で、行列はおそらくグローバルであり、メソッド内に存在していても、そのメソッドの外部から、たとえばメインの直後などにアクセスしようとすると、セグメンテーション違反が発生します。

コードをもう少し明確にするための別の編集。

このコードは実際に機能し、このメソッドを呼び出した後、height明らかに初期化していたことがわかりました。みんなの時間を無駄にするのは悪いことです。width

4

4 に答える 4

0

[何でも]へのポインタへのポインタから始める場合、おそらく行列を作成するために行っているのではなく、ポインタの配列を作成する(実際に割り当てる)ために行っているのです。次に(それを使って何でもできるように)、ポイントするポインターのそれぞれにいくらかのスペースを割り当てる必要があります。

int generateMatrices(int rows, int columns) {
    image = malloc(sizeof(int *) * rows;
    if (image == NULL)
        return 0;
    for (int i=0; i<rows; i++) {
        image[i] = malloc(sizeof(int) * columns);
        if (image[i] == NULL)
            return 0;
   }
   return 1;
}

また、基本的に同じことを逆に行う(または名前を付けたいもの)を提供することdestroyMatricesもできます。行をウォークスルーし、各行を解放してから、ポインターの配列を解放します。

于 2012-06-13T16:54:47.807 に答える
0

投稿したコードは機能しますが、マトリックスが作成されないことに注意してください。マトリックスを作成する場合、このタスクははるかに複雑です。

これを行うには2つの簡単な方法があり、そのうちの1つは他の方法よりもはるかに簡単です。

シナリオ1:範囲の1つはコンパイル時に修正されます。

これにより、コードが非常に単純になります。次のことを考慮してください。

int (*image)[height] = NULL;
int width;

void generateMatrices()
{
    free(image); // in case it's already been allocated
    image = malloc(sizeof(image) * width); // you are done, you can now access the matrix
}

シナリオ2:複数の柔軟性の境界

int **image = NULL;
int width, height;

void generateMatrices()
{
    if (image)
    {
        free(*image); // in case it has already been allocated
        free(image);
    }

    image = malloc(sizeof(int *) * width);
    image[0] = malloc(sizeof(int) * width * height);
    for (int i = 1; i < width; i++)
        image[i] = (image[0] + (i * height));
}
于 2012-06-13T17:00:48.247 に答える
0

おそらく2D配列が必要だと思います。ここでは、ダブルポインタの1D配列のみを割り当てています。

1)ポインタからポインタへの配列を生成し(int**)ます; これは、2D配列の「ヘッダー」のようなものです。2)その最初の配列の各要素は別のポインターを指しています。この2番目のポインターは1次元配列であり、2次元配列または行列の単一の行と考えることができます。したがって、最初の配列をループしてから、(int**)別のmallocを実行して、必要な列幅の行[(int *)]の配列を作成します。

理解しておくべき重要なことは、すべての配列を最初の要素へのポインターとして、その最初の要素からのオフセットと組み合わせて扱うことができ、ポインターが他のポインターを指すことができるということです。したがって、行を指すポインターの配列があり、各行は順番にポインター+オフセットになります(従来の配列の意味では、おそらく期待します)。

ここでコードスニペットを試してください:http: //pleasemakeanote.blogspot.com/2008/06/2d-arrays-in-c-using-malloc.html

于 2012-06-13T17:04:27.890 に答える
0

編集後、2D割り当ては問題ないようです。との値が間違っている可能性heightがあります。私はここであなたの例を試しました、そしてそれはとの適切な値のためにうまく働きますwidth heightwidth

于 2012-06-14T04:42:48.783 に答える