fgets 在 gdb 下遇到分段错误,但通常在 运行 时不会
fgets meets with segmentation fault under gdb but not when running normally
以下程序(什么都不做)运行没问题。
#include <stdio.h>
int main(int argc, char *argv[])
{
char *current_string = NULL;
fgets(current_string, 16, stdin);
return(0);
}
当我在 GDB 下 运行 时,fgets
调用会触发分段错误。
Program received signal SIGSEGV, Segmentation fault.
0x000000332ec67ee0 in _IO_getline_info_internal () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6_6.9.x86_64
(gdb) backtrace
#0 0x000000332ec67ee0 in _IO_getline_info_internal () from /lib64/libc.so.6
#1 0x000000332ec66d29 in fgets () from /lib64/libc.so.6
#2 0x0000000000400536 in main (argc=1, argv=0x7fffffffd4e8) at test.c:7
据我所知,我一直在关注 fgets
函数的正确用法,但我不明白发生了什么。我做错了什么?
我在 RHEL 上使用带有 -g
选项(用于调试信息)的 gcc 进行编译。
在您的代码中,
fgets(current_string, 16, stdin);
current_string
被初始化为 NULL
,所以本质上你是在试图写入一个无效的指针。它调用 undefined behaviour.
你需要先给current_string
分配内存,然后才能写入一些东西(进入内存位置指向通过它,准确地说)。
相反,根据 this 片段,我认为没有理由使用 current_string
作为 pointer。你可以很容易地写出类似
的东西
#define MAX 16
char current_string[MAX] = {0};
fgets(current_string, MAX, stdin);
并使其发挥作用。
您告诉 fgets() 写入地址 0 处的内存,该地址未分配给您。这是未定义的行为,在大多数情况下会导致段错误。我有点惊讶它并不总是如此,但我不在乎,这就是未定义行为的作用。
您需要使用 malloc() 调用为 fgets 分配缓冲区。
以下程序(什么都不做)运行没问题。
#include <stdio.h>
int main(int argc, char *argv[])
{
char *current_string = NULL;
fgets(current_string, 16, stdin);
return(0);
}
当我在 GDB 下 运行 时,fgets
调用会触发分段错误。
Program received signal SIGSEGV, Segmentation fault.
0x000000332ec67ee0 in _IO_getline_info_internal () from /lib64/libc.so.6
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6_6.9.x86_64
(gdb) backtrace
#0 0x000000332ec67ee0 in _IO_getline_info_internal () from /lib64/libc.so.6
#1 0x000000332ec66d29 in fgets () from /lib64/libc.so.6
#2 0x0000000000400536 in main (argc=1, argv=0x7fffffffd4e8) at test.c:7
据我所知,我一直在关注 fgets
函数的正确用法,但我不明白发生了什么。我做错了什么?
我在 RHEL 上使用带有 -g
选项(用于调试信息)的 gcc 进行编译。
在您的代码中,
fgets(current_string, 16, stdin);
current_string
被初始化为 NULL
,所以本质上你是在试图写入一个无效的指针。它调用 undefined behaviour.
你需要先给current_string
分配内存,然后才能写入一些东西(进入内存位置指向通过它,准确地说)。
相反,根据 this 片段,我认为没有理由使用 current_string
作为 pointer。你可以很容易地写出类似
#define MAX 16
char current_string[MAX] = {0};
fgets(current_string, MAX, stdin);
并使其发挥作用。
您告诉 fgets() 写入地址 0 处的内存,该地址未分配给您。这是未定义的行为,在大多数情况下会导致段错误。我有点惊讶它并不总是如此,但我不在乎,这就是未定义行为的作用。 您需要使用 malloc() 调用为 fgets 分配缓冲区。