2

flags で gcc バージョン 4.8.0 を使用してい-Wall -std=gnu99ます。

C で malloc を使用して、連続する 2D 配列にメモリを動的に割り当てる必要があります。この事実は譲れない。x[r][c]ただし、使いやすさのために、便利な表記法を使用して配列にアクセスできるようにしたいと考えています。これは、連続した 2D 配列へのポインターを作成し、次のようにして配列にインデックスを付ける私の勇敢な試み*array[r][c]です。

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

int main(void)
{
    size_t rows = 3, cols = 5;

    printf("sizeof(int) = %li\n\n", sizeof(int));

    int (*array)[rows][cols] = malloc(sizeof(int) * rows * cols);
    printf("array starts at %p\n", array);
    printf("sizeof(array) = %li\n", sizeof(array));
    printf("sizeof(array[0][0]) = 0x%lx\n", sizeof(array[0][0]));
    puts("");

    unsigned short r, c;

    for (r = 0; r <= rows - 1; r++) {
        for (c = 0; c <= cols - 1; c++) {
            printf("array[%i][%i] is at %p\n", r, c, &(*array[r][c]));
        };
        puts("");
    };
}

警告なしでコンパイルされますが、予期しない出力がいくつかあります。

sizeof(int) = 4

array starts at 0x16cc010
sizeof(array) = 8
sizeof(array[0][0]) = 0x14

array[0][0] is at 0x16cc010
array[0][1] is at 0x16cc024
array[0][2] is at 0x16cc038
array[0][3] is at 0x16cc04c
array[0][4] is at 0x16cc060

array[1][0] is at 0x16cc04c
array[1][1] is at 0x16cc060
array[1][2] is at 0x16cc074
array[1][3] is at 0x16cc088
array[1][4] is at 0x16cc09c

array[2][0] is at 0x16cc088
array[2][1] is at 0x16cc09c
array[2][2] is at 0x16cc0b0
array[2][3] is at 0x16cc0c4
array[2][4] is at 0x16cc0d8

ここで何が起こっているのかよくわかりません。要素は連続していますが、int には大きすぎ、配列は小さすぎてすべてを保持できません。

私の配列宣言は、私が最も確信が持てない部分です。「 intの配列 (ストライド付き) へのポインターですint (*array)[rows][cols]」と読んでいますが、明らかにそれは正しくありません。arraycols

ここで私は正確に何を間違っていますか?

4

2 に答える 2

6
int (*array)[cols] = malloc( sizeof *array * rows );

for (r = 0; r <= rows - 1; r++) {
    for (c = 0; c <= cols - 1; c++) {
        printf("array[%i][%i] is at %p\n", r, c, &array[r][c]);

はポインターを暗黙的に逆参照する ため、これによりarrayとしてインデックスを付けることができます。array[i][j]array[i]

割り当てを解除するには、電話するだけです

free( array );
于 2013-05-17T15:47:29.113 に答える
3

コードは

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

int main(void)
{
    size_t rows = 3, cols = 5;

    printf("sizeof(int) = %li\n\n", sizeof(int));

    int (*array)[rows][cols] = malloc(sizeof(int) * rows * cols);
    printf("array starts at %p\n", array);
    printf("sizeof(array) = %li\n", sizeof(*array));  // Note the *
    printf("sizeof(array[0][0]) = 0x%lx\n", sizeof((*array)[0][0]));
    puts("");

    unsigned short r, c;

    for (r = 0; r <= rows - 1; r++) {
        for (c = 0; c <= cols - 1; c++) {
            printf("array[%i][%i] is at %p\n", r, c, &((*array)[r][c]));
        };
        puts("");
    };
}

配列は配列[x][y]へのポインタであるため、最初に逆参照する必要があります

 (*array)

アイテムにアクセスする

 (*array)[x][y]

こうすれば得られる

sizeof(int) = 4

array starts at 0x12de010
sizeof(array) = 60
sizeof(array[0][0]) = 0x4

array[0][0] is at 0x12de010
array[0][1] is at 0x12de014
array[0][2] is at 0x12de018
array[0][3] is at 0x12de01c
array[0][4] is at 0x12de020

array[1][0] is at 0x12de024
array[1][1] is at 0x12de028
array[1][2] is at 0x12de02c
array[1][3] is at 0x12de030
array[1][4] is at 0x12de034

array[2][0] is at 0x12de038
array[2][1] is at 0x12de03c
array[2][2] is at 0x12de040
array[2][3] is at 0x12de044
array[2][4] is at 0x12de048

これは、期待される値の範囲内にあります

于 2013-05-17T15:47:21.737 に答える