3

解析中のタブ区切りのテキスト ファイルがあります。その最初の列には、「1」、「2」、...、「X」、「Y」などの一連の文字列を示す形式chrXの文字列が含まれます。X

ファイルが解析されると、これらはそれぞれchar*呼び出された に格納されます。chromosome

テキスト ファイルは、最初の列で辞書式に並べ替えられます。つまり、"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*chr1FILE*

fcloseセグメンテーション違反が発生する原因となっているこの呼び出しの原因は何ですか?

4

8 に答える 8

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

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

編集:--db-attachへのオプションvalgrindは、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

于 2009-09-18T08:16:09.653 に答える
5

私が気付く1つのエラーは次の行です:

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

次のようになります。

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

これは、文字列の末尾に 0 があり、そのためのスペースも確保する必要があるためです。

于 2009-09-18T08:15:26.750 に答える
1

reinierによって検出されたエラーに加えて、次のように思われます。

free(chromosome);

後に続く必要があります:

chromosome = NULL;

有効でなくなった値が使用される可能性を防ぐため。

于 2009-09-18T08:34:29.343 に答える
1

一般的なポインターの問題

C は優れた言語ですが、自分の記憶を壊さないようにする必要があります。malloc が 1 バイト短いという前述の問題に加えて、他のポインターの問題が発生する可能性があります。

メモリ デバッガを使用することをお勧めします。昔はElectric Fenceが流行っていましたが、最近はvalgrind をよく耳にします。他にもたくさんの選択肢があります。

于 2009-09-18T08:23:45.670 に答える
1

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

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

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

于 2009-09-18T08:20:17.203 に答える
0

この FILE* filePtr だけで十分なのに、なぜこの FILE** filePtr なのか? ちょっとした考え...

于 2009-10-21T14:58:43.587 に答える