1

ファイルを文字列に読み取り、古いプログラムから文字列を出力するコードをコピーしました。正常に動作していたので、少し変更することにしました。新しいプログラムは

#include <stdio.h>
#include <string.h>

int main() {
    FILE *itemlist = fopen("itemlist", "r");
    char *currentstring, charbuffer[2];
    // char itemstart = 0;
    while (fgets(charbuffer, 2, itemlist)) {
        strcat(currentstring, charbuffer);
    }
    printf("%s", currentstring);
    return 0; 
}

そしてそれは期待通りに動作します。しかし、itemstart行のコメントを外すと、セグメンテーション違反が発生します。私はそれを使用していませんし、私に関する限り、charを0に初期化することは違法ではありません。タイプの問題だと思ったので、shortに変更してからintに変更しましたが、それでもセグメンテーション違反が発生していました。

しかし、それから私はその部分を取り除いて= 0、それは再び働きました。それから私はそれを元に戻し、gdbでバイナリをデバッグすることにしました、そしてsegfaultはにありましたstrcat

これはどのように可能ですか?

4

4 に答える 4

4

currentstringダングリングポインタであるためstrcat(currentstring, charbuffer);、未定義の動作になります。

おそらくコメントを外すと、char itemstart = 0一部のメモリが初期化され0、アクセス違反が表示されますが、これは単なる推測です。未定義の動作は、何かが起こる可能性があることを意味します。

次のメモリを割り当てる必要がありますcurrentstring

currentstring = malloc(10); //or whatever length you need
于 2012-04-13T20:14:15.180 に答える
1

無関係な行のコメントを外すときのセグフォールトは、C言語の安全性が低いために可能になります。正しくないプログラムの終了動作は、コンパイラーによる微妙な選択によって決定されます。

このような狂気に直面したときは、最初にコードを修正してみてください。もちろん、これは必ずしも簡単ではありません。8行のプログラムでは、大丈夫です。

于 2012-04-13T20:17:06.273 に答える
1

currentstringにいくらかのスペースを割り当てる必要があります。

于 2012-04-13T20:13:51.200 に答える
1

currentstringセグメンテーション違反/ヒープの破損を回避するために、変数にスペースを割り当て、そのサイズを制御する必要があります。

#define MAX_BUFFER_SIZE 32
//...
FILE *itemlist = fopen("itemlist", "r");
char *currentstring = malloc(MAX_BUFFER_SIZE+1);
char *tmpbuf;
char charbuffer[2];
// char itemstart = 0;
int bytesloaded = 0;
while (fgets(charbuffer, 2, itemlist)) {

    if(bytesloaded + 2 > buf_size) {
       /* call realloc() */
        buf_size += MAX_BUFFER_SIZE;
        tmpbuf = realloc(currentstring, buf_size);
        if(tmpbuf == NULL) { /* Get off loop. Using break or return. */
             break; 
        } 
        currentstrig = tmpbuf;
     }
    memcpy(currentstring + bytesloaded, charbuffer, 2);
    bytesloaded += 2;
}
//... 
free(currentstring);

私はテストしていませんが、うまくいくと思います。

于 2012-04-13T20:36:16.917 に答える