0

我在 C 中运行一个程序。当我运行该程序时,我得到一个分段错误错误。在 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);

当我将 strlen 更改为 sizeof 时,错误停止。

我的代码有什么问题?

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 回答