5

Cでmalloc.hを学び始めました。アイデアは、動的配列を作成することでした。コードは次のとおりです。

#include <stdio.h>
#include <conio.h>
#include <malloc.h>

int main() {
    int *array = (int*)malloc(sizeof(int));
    int i, j, val;
    for (i = 0;; i++) {
        array = (int*)realloc(array, sizeof(int) + sizeof(*array));
        printf("Enter array[%d]=", i);
        scanf("%d", (array + i));
        if (*(array + i) == 0) break;
    }
    for (j = 0; j < i; j++) {
        printf("[%d] = %d\n", j, *(array + j));
    }
    getch();
    return 0;
}

結果は

Enter array[0]=1
Enter array[1]=2
Enter array[2]=3
Enter array[3]=4
Enter array[4]=5
Enter array[5]=6
Enter array[6]=7
Enter array[7]=8
Enter array[8]=9
Enter array[9]=10
Enter array[10]=0
[0] = 1
[1] = 2
[2] = 3
[3] = 4
[4] = 5
[5] = 6
[6] = 7
[7] = 8
[8] = 542979931
[9] = 875896893

毎回、>=8値はランダムです。なぜそうなったのかさっぱり分からないのですが、何が悪いのでしょうか?

4

4 に答える 4

7

コード内の未定義の動作。私は、これを行うと思います:

array=(int*)realloc(array,sizeof(int)+sizeof(*array));

配列全体のサイズが返されるsizeof(*array)と思いますよね?しかし、そうではありません。sizeofはコンパイル時に計算され、実行sizeof(*array)は実際には と同じsizeof(int)です。

したがって、この配列を拡張可能にするには、現在の要素数を保持する変数を追加し、次のようにする必要があります。

array=(int*)realloc(array, sizeof(int) + current_size_of_array * sizeof( int ) );

whereは、実際にもう 1 つの要素を追加すると、current_size_of_arrayの各ループでインクリメントされます。for

于 2013-03-29T13:03:27.523 に答える
3

sizeof(*array)配列の大きさはわかりません。int が占めるバイト数を示します。したがって、realloc を呼び出すたびに、2 つの int 値にのみメモリが割り当てられます。必要な整数の数reallocを割り当てるように呼び出しを変更します。sizeof(int)

于 2013-03-29T13:03:09.617 に答える
2

sizeof(int)+sizeof(*array)

sizeof(*array)すでに割り当てられているバイト数だと思います。あなたは間違っている、sizeof(*array)1 つのサイズですint。したがって、バッファをオーバーランしているため、最終的に問題が発生します。

尋ねる前に、既に割り当てられているサイズを取得する標準的な方法はありません。malloc通常は、自分で保存する必要があります (または、C++ では、 などの よりもユーザー フレンドリーなインターフェイスを持つものを使用しますvector)。この場合、既存のサイズは必要ありません。必要な新しいサイズを から計算できますi

于 2013-03-29T13:03:33.100 に答える
1

The size of a block of memory allocated by malloc is known to the library (free only needs the pointer) but there is no portable way to get that number back. You must store in some other variable what is the current size so that you can allocate more space.

In sizeof(*array) the sizeof operator only considers the type of the expression and in your case is (*(int *)) in other words is the same as sizeof(int).

In C++ this work of remembering the number of elements inside a dynamic array allowing increasing the size is done by the standard class std::vector.

As a side note please remember that x = realloc(x, ...); is a bad idiom because in case of allocation failure your pointer x would be overwritten by NULL leaking that memory.

于 2013-03-29T13:08:58.783 に答える