2011-09-16 14 views
2

私は、次のコードを書いた:それはSIGSEGVでクラッシュ信号11(SIGSEGV)

FILE *book; 
wchar_t bufferln[FILE_READ_BUFFER]; 
wchar_t buffer[FILE_READ_BUFFER]; 
book = fopen(file, "r"); 
if(book == NULL){ 
    perror("Es ist ein Fehler beim lesen des Buches aufgetreten"); 
    return EXIT_FAILURE; 
} 
while(fgetws(buffer, FILE_READ_BUFFER, book) != NULL){ 
    if(wcscmp(buffer, L"\n") == 0){ 
     bufferln[0] = L'\0'; 
     continue; 
    } 
    buffer[wcsnlen(buffer, FILE_READ_BUFFER)-1] = L' '; 
    wcsncat(bufferln, buffer, FILE_READ_BUFFER); 
} 
return EXIT_SUCCESS; 

を。私は次のことを示しているvalgrindのを実行しました:

==11251== Conditional jump or move depends on uninitialised value(s) 
==11251== at 0x40BD5CF: wcsncat (wcsncat.c:36) 
==11251== by 0x804865D: read_book (book.c:18) 
==11251== by 0x804872B: main (main.c:19) 
==11251== Uninitialised value was created by a stack allocation 
==11251== at 0x80485B7: read_book (book.c:3) 
==11251== 
==11251== Invalid read of size 4 
==11251== at 0x40A58E2: fgetws (iofgetws.c:52) 
==11251== by 0x804867D: read_book (book.c:12) 
==11251== by 0x6D: ??? 
==11251== Address 0x65 is not stack'd, malloc'd or (recently) free'd 
==11251== 
==11251== 
==11251== Process terminating with default action of signal 11 (SIGSEGV) 
==11251== Access not within mapped region at address 0x65 
==11251== at 0x40A58E2: fgetws (iofgetws.c:52) 
==11251== by 0x804867D: read_book (book.c:12) 
==11251== by 0x6D: ??? 
==11251== If you believe this happened as a result of a stack 
==11251== overflow in your program's main thread (unlikely but 
==11251== possible), you can try to increase the size of the 
==11251== main thread stack using the --main-stacksize= flag. 
==11251== The main thread stack size used in this run was 8388608. 

私は問題は何とかwcsncatの私の使用法に関連していると思います(多分*ブックメモリへの書き込み?)が、なぜ? 文章(UTF-8)の段落を段落で読んで、それからこのコードにないものをやりたい。

答えて

1

は(あなたのwcsncatということです)のドキュメントに従っていた:

「 DESCRIPTION wcsncat()関数は、文字列の最初のn文字がにWS2によって指さよりも多くを追加していませんws1が指している文字列の終わりns文字の前にws2にNULL文字があれば、NULL文字までのすべての文字がws1に追加されます。ws2の最初の文字はws1の終了NULL文字を上書きします。常に結果に追加され、コピーに使用されるオブジェクトが重複する場合、その動作は未定義です。 "

これは、NULL文字の最初の出現を上書きすることから始まるbufferlnへの追加を続けます。したがって、(wcscmp(buffer、L "\ n")== 0)がFALSEを返す場合は、割り当てられたバッファのFILE_READ_BUFFERをオーバーランさせ、bufferln境界の外側にファイルを吐き出し、スタックを破損させる可能性があります。

ほとんどの場合、スタックは下向きになり、ほとんどのシステムでは仮想アドレスページの最初の2ページにアクセスすることができないため、実際にはFAULTする領域に達している必要があります。これは、なぜそれがそこに失敗したのかに関する疑問な点です。しかし主な理由は、読み書きバッファの長さが同じであるため、データを読んだらどこかでデータを書き込もうとする必要があるということです。私はWICH wcsncat使用

HTH

+0

w1がn個の文字に達するまで、wcsncatはx個の文字だけを追加すると予想しました。解決しました、ありがとう! –

0

行が空の場合(\ nは\ 0に置き換えられます)、文字列の長さはnullで、strlen()-1はバッファの下を指します。

編集: 私は間違っています。あまりにも多く追加しているだけです。バッファーサイズを大きくしたり、行数を減らしたり、その両方を読んでください。 そしてstrcat()を避けてください。

+0

パラメータとしてBUFFERSIZEを必要とし、さらに私は(1000等しい)FILE_READ_BUFFER標識を読み、文字列を処理するすべての機能に同じ定数を使用します。詳しくはどういう意味ですか? –

+0

申し訳ありません、私は間違っていました。 [私はちょっと嫌いです* str * cat()!!ちょうどカウント...]。ジョナサンはおそらくそれを正しくしました。バッファーは初期化されていません。 – wildplasser

2

bufferlnを初期化しないため、初期化されていないデータの末尾に新しい行を連結(wcsncat())すると、コードの書き込み先が分かりません。

また、入力バッファbufferの末尾にヌルターミネータの上に(ワイド)スペースを書き込むので、ランダムな場所に何がコピーされるのか分かりません。次回ワイドNULに当たるとコピーが停止します。起こって何ができるか

関連する問題