【发布时间】:2017-09-11 06:53:54
【问题描述】:
当我出于某种原因传递一个以 null 结尾的字符串时,printf() 会引发分段错误。
这是我在 GDB 中的问题的演示
λ sudo gdb -q notesearch 从notesearch读取符号...完成。 (gdb) 休息 53 0x400b32 处的断点 1:文件 notesearch.c,第 53 行。 (gdb) 运行 启动程序:/home/frosty/hack/chapter_2/code/notesearch [调试] 用户 ID:0 [调试] 文件描述符:3 断点 1,print_notes (fd=3, uid=0, searchstring=0x7fff3daf7fc0 "") 在 notesearch.c:53 53 printf("%s\n", note_buffer); (gdb) x/8xb note_buffer 0x7feb5a997168:0x68 0x65 0x6c 0x6c 0x6f 0x0a 0x00 0x00 (gdb) x/s note_buffer 0x7feb5a997168:“你好\n” (gdb) 下一个 程序收到信号 SIGSEGV,分段错误。 _dl_fixup (l=, reloc_arg=) 在 ../elf/dl-runtime.c:148 148 ../elf/dl-runtime.c:没有这样的文件或目录。 (gdb)这是解决问题的源代码
int print_notes(int fd, int uid, char *searchstring){ int note_length = find_user_note(fd, uid); 如果 (note_length == -1) 返回0; // 文件结束 char* note_buffer; 读取(fd,note_buffer,note_length); note_buffer[note_length] = 0; //空终止字节 如果(搜索笔记(笔记缓冲区,搜索字符串)){ printf("%s\n", note_buffer); } 返回 1; }【问题讨论】:
-
你有
char* note_buffer;,但从不分配内存。因此,当您使用它时,您将信息放入内存中,但您不知道在哪里。要么先分配内存,要么使用 char 数组。 -
@AntonH 虽然,我对它为什么起作用感到有点困惑。如果您查看我的 gdb 输出,
read()工作正常并读取了预期的字符串。是不是因为它在内存的另一个区域(堆除外)并且 printf 无法读取内存的特定区域? -
"我对它为什么起作用感到有点困惑" --> 代码违反了规则,使用未初始化的
note_buffer编写。 C 不需要合理的结果 - 欢迎来到 Undefined Behavior (UB)。 -
@TimothySamson 没用。看起来它有效,但实际上并没有。仅仅因为您看到了预期的结果,并不意味着它有效。正如“chux”所说,未定义的行为。
-
好的。非常感谢你们! :-)