当strlen产生分段错误时,来自GetString()的C字符串 [英] C string from GetString() when strlen produces segmentation fault
问题描述
我正在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屋!