0

(本質的には) 文字の 2 次元配列、つまり文字列の配列にメモリを動的に割り当てようとしています。

私のコードは次のとおりです。

typedef char LineType[MAX_CHARS+1];
LineType* lines;

int c = 0;
int N = 2;

lines = (LineType *) malloc (N * sizeof( LineType) );
do { 
    if (c > N ) {
        N *=2;
        lines = (LineType*) realloc (lines, N * sizeof( LineType));
    }

    .
    .
    .
    c++;

} while ( . . . )

これは正常にコンパイルされますが、実行時に失敗し、ヒープ破損の可能性と dbgheap.c での破損に関する警告が表示されます (in: _CrtIsValidHeapPointer)。

私は何を間違っていますか?おそらくデータ構造に固定/動的次元が混在していることが原因であると考えました...しかし、文字列の(さまざまなサイズの)配列にメモリを宣言して動的に割り当てる(および再割り当てする)最良の方法は何ですか?それぞれが固定サイズです)?

事前にどうもありがとう

2012 年 8 月 26 日更新

人々のコメントや提案に合わせてコードを少し変更しました。問題はまだ続きます...

4

3 に答える 3

2

cのインデックスに が使用されていると仮定すると、 ではなくlinesをテストする必要があります。c >= Nc > N

余談ですが、typedef を使用してコードを読みやすくすることをお勧めします。また、冗長な割り当てコードも避けます。

typedef char fixed_string[MAX_CHARS + 1];

int c = 0;
int N = 0;
fixed_string *lines = NULL;

do {
    if (c >= N ) {
        N = N ? 2*N : 2;
        lines = (fixed_string*) realloc (lines, N * sizeof(fixed_string));
    }
    ⋮
    c++;
} while (…);

さらに余談ですが、成長係数 2 を使用する場合は注意してください。同じアレイで再利用できない穴が残ります。1.5 倍 ( 3*N/2) の方が安全です。

編集:他のコメントから、再割り当ての時点でクラッシュが発生したことに注意してください。これは、配列の末尾を超えて書き込むことと一致しています。デバッグ メモリ アロケータは、割り当てられたメモリ ブロックのすぐ周囲のスペースを特殊なバイトで埋め、次にそのメモリ ブロックで何かを行うときにそれらのバイトが保持されることを確認します。HEAP CORRUPTION メッセージは、与えられたメモリの外側に書き込むことによって周囲のバイトが破損したことを示します。

于 2012-08-25T09:42:54.107 に答える
0

これは大間違い

lines = (LineType *) malloc (N, sizeof( LineType *) );

sizeof(LineType*)多数の文字列ではなく、単一のポインターにスペースを割り当てるためです。

(また、奇妙な「コンマ演算子」を使用して、1 つだけが期待される式を 2 つ持つことができます。これは、左側にあるものを評価して破棄し、右側にあるものを保持します。ここではあまり良くありません! )

より良い割り当ては

lines = malloc(N * sizeof(LineType));

ここで、 type の N 個のオブジェクトにスペースを割り当てますLineType

オブジェクト全体ではなくポインターにスペースを割り当てる、realloc にも同様の問題があります。

于 2012-08-25T12:39:34.963 に答える
0

読みやすくする:

それ以外の

char (*lines) [MAX_CHARS +1];

する

typedef char LineType[MAX_CHARS+1];
LineType* lines;

同様の方法で、

lines = (char (*) [MAX_CHARS +1]) calloc (N, sizeof( char (*) [MAX_CHARS +1]));
...
lines = (char (*) [MAX_CHARS + 1]) realloc (lines, N * sizeof( char (*) [MAX_CHARS +1]));

になる

lines = malloc(N*sizeof(LineType));
...
lines = realloc(lines, N * sizeof(LineType));

注: calloc を使用したことがないという理由だけで、calloc を malloc に置き換えました。

いずれにせよ、typedef を小さくすると、読みやすさが大幅に向上します。読みやすいコードは簡単に理解できます。

于 2012-08-25T09:47:37.930 に答える