当strlen产生分段错误时,来自GetString()的C字符串

时间:2013-04-09 01:53:10

标签: c string segmentation-fault strlen cs50

我在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 for 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;
}

1 个答案:

答案 0 :(得分:4)

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);

将分配缩小到正确的大小。