2016-10-11 12 views
3

私は数時間前からこの問題に苦労していましたが、何が起こっているのか迷っています。これはprogram.cをのためのコードです:Linuxの'mallocced'配列のインデックスを作成する際にセグメンテーションエラーが発生する

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

#define SPACE 32 
#define INITIAL 4 

typedef struct { 
    char *town; 
    char *country; 
} town_t; 

typedef struct { 
    int num_towns, current_size; 
    town_t **towns_list; 
} index_t; 

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

    index_t town_index; 
    town_index.current_size = INITIAL; 
    town_index.towns_list = malloc(town_index.current_size * sizeof(*(town_index.towns_list))); 
    assert(town_index.towns_list != NULL); 

    printf("Step: %d\n", 1); 
    town_index.towns_list[0]->town = malloc(4 * sizeof(*(town_index.towns_list[0]->town))); 
    printf("Step: %d\n", 2); 
    assert(town_index.towns_list[0]->town != NULL); 

    return 0; 
} 

これは、それが実行される方法です:

./program 
Step: 1 
Segmentation fault 

を私が期待するとして、Windows上では

program.exe 
Step: 1 
Step: 2 

を出力し、それは本当に助けにはならない。しかし、Linuxの出力では、明らかに最初のprint文が実行されていますが、2番目のprint文は実行されていません。特に、私はtown_index.towns_list[0]をやっていると私の問題を引き起こしていると思いますが、私は理由を言うことができません。

これは、比較的複雑なデータ構造であるので、多分私はいくつかの点で迷子になっています。基本的にはtown_indexは現在の町の数がtowns_listcurrent_sizeで、町を救うために現在利用可能なスペースを反映したインデックス構造体を意味します。また、文字列として名前と国を含むtown_tへのポインタの配列も含まれています。

私はValgrindを使用しようとしましたが、本当に助けにならないのです。ご覧になりたい方はPastebinです

これは私がどんな心のマジックナンバーとその他もろもろ別のプログラムで経験し、そうされなかったかの単純化したシナリオです。

これはVirtualBox Linux Mint 64ビット版です。


誰もができることがあれば:Valgrindに正確な行を表示させるにはどうすればよいですか?他のどこでもオンラインで見ることができますが、私の出力はプログラムと機能があるフォルダを教えてくれるだけで、あまり役に立ちません。

+1

ようこそスタックオーバーフロー!デバッガを使用してコードをステップ実行する方法を学ぶ必要があるようです。良いデバッガを使用すると、プログラムを1行ずつ実行し、どこからずれているかを確認することができます。これはプログラミングをする場合に不可欠なツールです。さらに読む:[小さなプログラムをデバッグする方法](http://ericlippert.com/2014/03/05/how-to-debug-small-programs/) –

+0

は、最初のmalloc – Toby

+1

に優しい勧告をtown.index.towns_listのはsizeofを取ったときにアスタリスクを逃し考える:彼らはPOSIXによって暗黙的に標準によると、明示的に予約されているとして、型名を示すために、接尾辞 '_t'を使用していません標準。 ([ヒント](https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html)) –

答えて

4

town_index.towns_listを初期化しましたが、town_index.towns_list[0]を初期化していないので、town_index.towns_list[0]->townは未定義の動作です。

あなたは二次元に

for (int i = 0; i < town_index.current_size; ++i) 
    town_index.towns_list[i] = malloc(sizeof **town_index.towns_list); 

のようなものを逃しました。

+0

素晴らしい、ちょうど私が必要なもの、おかげでトン!これはそれをクリアし、また私が取り組んでいた大きなプログラムを修正しました:) – Arkantos

0

town_index.towns_listtown_index.towns_list[0]は同じではありません。 town_index.towns_listを初期化しますが、town_index.towns_list[0]は0に等しいです。逆参照によって引き起こされるクラッシュtown_index.towns_list[0]

関連する問題