質問

解析中のタブ区切りテキストファイルがあります。最初の列には、 chrX という形式の文字列が含まれます。ここで、 X は文字列のセットを示します(例:" 1"、" 2"、...、" X"、" Y"。

これらは、ファイルが解析されるときに、 chromosome と呼ばれる char * にそれぞれ保存されます。

テキストファイルは、辞書式に最初の列でソートされます。つまり、「chr1」で始まり、次に「chr2」などで始まる行がいくつかあります。

各" chrX"でエントリ、このエントリに関連付けられている別のファイルを開く必要があります:

FILE *merbaseIn;

// loop through rows...

if (chromosome == NULL)                                                                                                                                                   
    openSourceFile(&chromosome, fieldArray[i], &merbaseIn, GENPATHIN);                                                                                                      
else {                                                                                                                                                                    
    if (strcmp(chromosome, fieldArray[i]) != 0) { // new chromosome                                                                                                   
        fclose(merbaseIn); // close old chromosome FILE ptr                                                                                                                                                                                                                                    
        free(chromosome); // free old chromosome ptr                                                                                                                          
        openSourceFile(&chromosome, fieldArray[i], &merbaseIn, GENPATHIN); // set up new chromosome FILE ptr                                                                  
    }                                                                                                                                                                       
}  
// parse row

次のように定義されている関数 openSourceFile があります:

void openSourceFile (char** chrome, const char* field, FILE** filePtr, const char *path) {
    char filename[100];                                                                                                                                                           
    *chrome = (char *) malloc ((size_t) strlen(field));
    if (*chrome == NULL) {                                                                                                                                                        
        fprintf(stderr, "ERROR: Cannot allocate memory for chromosome name!");                                                                                                      
        exit(EXIT_FAILURE);                                                                                                                                                         
    }                                                                                                                                                                             

    strcpy(*chrome, field);                                                                                                                                                       
    sprintf(filename,"%s%s.fa", path, field);                                                                                                                                     

    *filePtr = fopen(filename, "r");                                                                                                                                              
    if (*filePtr == NULL) {                                                                                                                                                       
        fprintf(stderr, "ERROR: Could not open fasta source file %s\n", filename);                                                                                                  
        exit(EXIT_FAILURE);                                                                                                                                                         
    }                                                                                                                                                                             
}      

問題は、次の行でセグメンテーションフォールトが最初の染色体から2番目の染色体( chr1 から chr2 )に移動して終了することです。最初に開いた染色体ファイル:

fclose(merbaseIn);

fclose にNULLポインターを渡していないのはわかっています。セグメンテーションフォールトまでは、このファイルからデータを読み取っているためです。条件でこれをラップすることもできますが、それでも障害が発生します:

if (merbaseIn != NULL) {
    fclose(merbaseIn);
}

さらに、私は openSourceFile が機能することを知っています(少なくとも chr1 では、 FILE * の最初のファイルハンドルを設定するとき) chr1 行を解析し、 FILE * ソースファイルからデータを正しく読み取ります。

セグメンテーションフォールトを発生させているこの fclose 呼び出しについてはどうですか?

役に立ちましたか?

解決

valgrind --db-attach=yes --leak-check=yes --tool=memcheck --num-callers=16 --leak-resolution=high ./yourprogram args

セグメンテーション違反は、ローカルの人に影響を与えるものではなく、ヒープのメモリ破損が原因である可能性が非常に高いです。 Valgrind は、最初に行った誤ったアクセスをすぐに表示します。

編集: valgrind -db-attach オプションは、2014年のリリース3.10.0から非推奨になりました。リリースノートの状態:

The built-in GDB server capabilities are superior and should be used
instead. Learn more here:

http://valgrind.org /docs/manual/manual-core-adv.html#manual-core-adv.gdbserver

他のヒント

1つのエラーは次の行にあります:

 *chrome = (char *) malloc ((size_t) strlen(field));

これは次のとおりです:

 *chrome = (char *) malloc ((size_t) strlen(field)+1);

これは、文字列の末尾に0があり、そのためにスペースを空ける必要があるためです

最良の推測は、コードの他の部分がバッファオーバーランまたは同様のバグによりメモリを破損していることです。

原因ではないが、完全なファイル名が100文字を超えると、ファイル名配列にオーバーラン状態が発生する可能性があります。

デバッガを使用して、merbaseIn変数によって使用されるメモリ位置の変化を監視することをお勧めします。

汎用ポインターの問題

Cは素晴らしい言語ですが、自分の記憶を壊さないことが必要です。 mallocが1バイト短い場合に前述した問題に加えて、他のポインターの問題がある可能性があります。

メモリデバッガの使用をお勧めします。過去には、エレクトリックフェンスはかなり人気がありましたが、最近では valgrindの詳細をご覧ください。他にもたくさんの選択肢があります。

reinier で見つかったエラーに加えて、

free(chromosome);

の後には次のようにする必要があります:

chromosome = NULL;

無効な値が使用される可能性を防ぐため。

このFILE * filePtrだけで十分な場合、なぜこのFILE ** filePtrなのか? ただの考え...

memcheck を使用した

valgrind は、セグメンテーション違反の原因を発見するための間違いなく正しいツールです。 valgrind でデバッガを使用するには、-db-attach オプションの valgrind がValgrind 3.10.0のリリース後に廃止されていることに注意してください。 2014.リリースノートの状態:

The built-in GDB server capabilities are superior and should be used
instead. Learn more here:

http://valgrind.org /docs/manual/manual-core-adv.html#manual-core-adv.gdbserver

" malloc" を使用したすべての場所を確認し、間違えたかどうかを確認します。

たとえば、ファイルから読み取った行をchar **に入れていましたが、間違っています malloced as ::

my_list = malloc(sizeof(char) * num_lines_found_in_file);

本来あるべき時:

my_list = malloc(sizeof(char*)* num_lines_found_in_file);
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top