0

C でプログラムを実行しています。プログラムを実行すると、セグメンテーション違反エラーが発生します。IN gdb バックトレースすると、それが教えてくれます

プログラム受信信号 SIGSEGV、セグメンテーション違反。__strlen_sse2_bsf () at ../sysdeps/i386/i686/multiarch/strlen-sse2-bsf.S:51 51 movdqu (%edi), %xmm1

私はそれがstrlenに関係していると信じています。

strlen を使用するのは次の場合だけです。

    string s = GetString();

    int stringlength = strlen(s);

sizeof の strlen を変更すると、エラーが停止します。

コードの何が問題になっていますか?

GetString のドキュメント

/*
 * Reads a line of text from standard input and returns it as a 
 * string (char *), sans trailing newline character.  (Ergo, if
 * user inputs only "\n", returns "" not NULL.)  Returns NULL
 * upon error or no input whatsoever (i.e., just EOF).  Leading
 * and trailing whitespace is not ignored.  Stores string on heap
 * (via malloc); memory must be freed by caller to avoid leak.
 */

string GetString(void) {
    // growable buffer for chars
    string buffer = NULL;

    // capacity of buffer
    unsigned int capacity = 0;

    // number of chars actually in buffer
    unsigned int n = 0;

    // character read or EOF
    int c;

    // iteratively get chars from standard input
    while ((c = fgetc(stdin)) != '\n' && c != EOF)
    {
        // grow buffer if necessary
        if (n + 1 > capacity)
        {
            // determine new capacity: start at 32 then double
            if (capacity == 0)
                capacity = 32;
            else if (capacity <= (UINT_MAX / 2))
                capacity *= 2;
            else
            {
                free(buffer);
                return NULL;
            }

            // extend buffer's capacity
            string temp = realloc(buffer, capacity * sizeof(char));
            if (temp == NULL)
            {
                free(buffer);
                return NULL;
            }
            buffer = temp;
        }

        // append current character to buffer
        buffer[n++] = c;
    }

    // return NULL if user provided no input
    if (n == 0 && c == EOF)
        return NULL;

    // minimize buffer
    string minimal = malloc((n + 1) * sizeof(char));
    strncpy(minimal, buffer, n);
    free(buffer);

    // terminate string
    minimal[n] = '\0';

    // return string
    return minimal;
}
4

1 に答える 1

5

関数の説明にはgetString()、エラーまたは EOF で NULL を返す可能性があることが明確に記載されています。

チェックせずに戻り値を渡すstrlen()と、プログラムがクラッシュします。

string s = GetString();
int stringlength = 0;

if (s != 0)
    stringlength = strlen(s);

これは少なくともクラッシュしません。

また、原因がどれほど混乱を招き、typedef char *string;それがもたらす利益がどれほど少ないかに気づき、それを心に留めるかもしれません. あなたを教えている人の過ちを繰り返す必要はありません。

私はまた、コードフラグメントを観察します:

// minimize buffer
string minimal = malloc((n + 1) * sizeof(char));
strncpy(minimal, buffer, n);
free(buffer);

より良く、より簡単に、次のように記述できます。

string minimal = realloc(buffer, n + 1);

割り当てを正しいサイズに縮小します。

于 2013-04-09T03:28:31.437 に答える