2017-02-15 12 views
0

私はC言語の新機能であり、構造体内に動的な配列を持たせようとしていますが、動的な項目数を追加する必要があります。C - 再配置後の構造体クラッシュの動的配列

コンテナの初期化時にmallocに大きい数字(+100000など)を使用すると、プログラムは正常に動作します。

sizeof(struct ...)メモリを割り当てて、reallocを使用して再割り当てしようとすると、新しい項目を配列に追加しようとするとプログラムがクラッシュします。再割り当てするときに+1000000のサイズを追加しても、それはまだクラッシュしますが、最初に割り当てるときに同じサイズが機能します。

は私の問題を表示するためのコードをダウンカット:

struct Station { 
    char name[100]; 
}; 

struct StationContainer { 
    int numberOfStations; 
    struct Station *stations[]; 
}; 

struct StationContainer *makeContainer() { 
    struct StationContainer *new; 
    // If I add +1000000 in size here, the program works fine 
    new = (struct StationContainer *) malloc(sizeof(struct StationContainer)); 

    if (new == NULL) { 
     fprintf(stderr, "makeContainer: out of memory\n"); 
     exit(1); 
    } 

    new->numberOfStations = 0; 

    return new; 
} 

int main(int argc, int argv[]) { 

    // Initialize the container 
    struct StationContainer *container; 
    container = makeContainer(); 

    // Add new station to container 
    struct Station *new; 
    new = (struct Station *) malloc(sizeof(struct Station)); 

    if (new == NULL) { 
     fprintf(stderr, "makeStation: out of memory\n"); 
     exit(1); 
    } 

    strcpy(new->name, name); 

    // Add to the container 
    // Even if I add +1000000 here, it still crashes below when I add new item 
    container = (struct StationContainer *) realloc(container, sizeof(struct StationContainer) + 1000000); 

    if (container == NULL) { 
     fprintf(stderr, "makeStation: container out of memory\n"); 
     exit(1); 
    } 

    container->stations[container->numberOfStations] = new; 
    container->numberOfStations++; 


} 

EDIT1: 私のカットダウンバージョンで問題が発見された、私はフルバージョンに戻ったらしかし、私はまだエラーを取得しました。私はcontainer out of memoryを得た。それは、私のcontainer->numberOfStationsが何らかの理由で最初のインクリメントの後に大きく大きくなったからです。

での私の完全なコード: codepad

adjacencies.txtファイルの内容:私は駅を作るとき、私は変わらずcontainer->numberOfStationsを残せば

Baker Street, Bond Street, Regent's Park 
Bond Street, Marble Arch, Baker Street, Oxford Circus, Green Park 
Marble Arch, Bond Street 
Green Park, Bond Street, Oxford Circus, Piccadilly Circus 
Regent's Park, Baker Street, Oxford Circus 
Oxford Circus, Bond Street, Regent's Park, Warren Street, Tottenham Court Road, Piccadilly Circus 
Piccadilly Circus, Green Park, Oxford Circus, Leicester Square, Charing Cross 
Warren Street, Oxford Circus, Goodge Street 
Goodge Street, Warren Street, Tottenham Court Road 
Tottenham Court Road, Oxford Circus, Goodge Street, Holborn, Leicester Square 
Leicester Square, Piccadilly Circus, Tottenham Court Road, Covent Garden, Charing Cross 
Charing Cross, Piccadilly Circus, Leicester Square 
Covent Garden, Leicester Square, Holborn 
Holborn, Tottenham Court Road, Chancery Lane 
Chancery Lane, Holborn 

、問題はありません。しかし、私は少なくともそれを一度増やして、reallocと組み合わせると、巨大な数に変わります。出力例:

Number of stations: 0 
!Station name:[Baker Street] 
Number of stations: 1 
!Station name:[Bond Street] 
Number of stations: 4067560 
makeStation: container out of memory 

私は1だけインクリメントするはずの乱暴にもかかわらず、私のnumberOfStationの変更を行うことどこかに小さな誤りがあるように感じますか?

+1

最初の注意:mallocの戻り値をキャストしないでください。 2番目の注意:変数 'new'を呼び出すことはお勧めしません。 'name'はどこで宣言されていますか? 'strcpy(new-> name、name);' –

+0

私のUni講義のノートにちょうど従っていました。 – Giedrius

+0

'gdb'を使ってエラーを受け取っている入力と正確な行がありますか? – Jarvis

答えて

2

まあ - だから、makeContainerちょうどそれをあなたも情報を持っているポインタのためのメモリを割り当てられても初期化されていないなどのポインタのための十分なスペースを与えるのでstationsはポインタ

ある

struct StationContainer { 
    int numberOfStations; 
    struct Station *stations[]; 
}; 

を見てnumberOfStations。それだけで初期化されていないポインタ

PSです:これは

strcpy(new->name, name); 

をコンパイル掲載元のバージョンではname

+0

割り当てます。彼はそのポインタで 'new'を指しています。 –

+0

Eh? 'name'は宣言されていません。 'new-> name'はメモリを持っています –

+1

@Tony' container-> stations'は定義されていませんので、その要素にアクセスすることはできません –

4

の宣言を見つけることができませんん、container->numberOfStationsは初期化されていないでした。
makeContainerでは、calloc()またはmemset()を使用してコンテナをゼロに初期化することができます。新しい項目を構造体に追加するときにうまく動作し、ゼロに初期化する必要があります。

現在のバージョンではエラーは検出されず、どちらもvalgrindとなります。私はnameと宣言する自由を100文字制限の制約の範囲内で取った。

+0

良い目。あなたが答えたことに気付かなかった。 :)削除された鉱山。 –

+0

いいえ、このプレビューのコードを削除すると誤って削除されました。私はそれがどのように表示されるように今編集します。 – Giedrius

+0

私は自分のエラーをどうやって得るかを正確に示す別の編集をしました。私が 'container-> numberOfStations'を1つ増やそうとすると起こります。 'codepad.org'も完全なコードへのリンクを追加しました。あなたの助けをありがとう! – Giedrius