当strlen产生分段错误时,来自GetString()的C字符串 [英] C string from GetString() when strlen produces segmentation fault

查看:286
本文介绍了当strlen产生分段错误时,来自GetString()的C字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在C中运行一个程序。当我运行该程序时,出现了分段错误错误。在gdb中,当我回溯时,它告诉我

I am running a program in C. When I run the program I get a segmentation fault error. IN gdb when I backtrace it tells me


程序收到信号SIGSEGV,分段错误。
__strlen_sse2_bsf()位于../sysdeps/i386/i686/multiarch/strlen-sse2-bsf.S:51 51 movdqu(%edi),
%xmm1

Program received signal SIGSEGV, Segmentation fault. __strlen_sse2_bsf () at ../sysdeps/i386/i686/multiarch/strlen-sse2-bsf.S:51 51 movdqu (%edi), %xmm1

我相信这与strlen有关。

I believe it has to do with strlen.

我唯一使用strlen的时间是:

The only time I use strlen is:

    string s = GetString();

    int stringlength = strlen(s);

当我更改为sizeof错误而停止时。

When I change strlen for sizeof error stops.

我的代码有什么问题?

What is wrong with my code?

GetString文档

Documentation of 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;
}


推荐答案

getString()函数明确指出它可以在错误或EOF上返回NULL。

The description of the getString() function clearly states that it can return NULL on an error or on EOF.

如果传递返回值更改为 strlen()时,程序将崩溃。

If you pass the return value to strlen() without checking, your program will crash.

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

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

这至少不会崩溃。

您可能还会注意到 typedef char * string; 造成了多少混乱,并带来了多少好处,请您多加注意。您不必重复那些教给您的错误。

You might also notice how much confusion the typedef char *string; causes and how little benefit it confers, and take it to heart. You don't have to repeat the mistakes of those who are teaching you.

我还观察到代码片段:

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

可能会更好,更简单些,写为:

could be better, and more simply, written as:

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

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

to shrink the allocation to the correct size.

这篇关于当strlen产生分段错误时,来自GetString()的C字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆