printf()会抛出分段错误。
这是GDB中我的问题的演示
λ sudo gdb -q notesearch Reading symbols from notesearch...done. (gdb) break 53 Breakpoint 1 at 0x400b32: file notesearch.c, line 53. (gdb) run Starting program: /home/frosty/hack/chapter_2/code/notesearch [DEBUG] UserID: 0 [DEBUG] File Descriptor: 3 Breakpoint 1, print_notes (fd=3, uid=0, searchstring=0x7fff3daf7fc0 "") at 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: "hello\n" (gdb) next Program received signal SIGSEGV, Segmentation fault. _dl_fixup (l=, reloc_arg=) at ../elf/dl-runtime.c:148 148 ../elf/dl-runtime.c: No such file or directory. (gdb)
这是问题的源代码
int print_notes(int fd, int uid, char *searchstring){ int note_length = find_user_note(fd, uid); if (note_length == -1) return 0; // End of file char* note_buffer; read(fd, note_buffer, note_length); note_buffer[note_length] = 0; // null terminator byte if(search_note(note_buffer, searchstring)) { printf("%s\n", note_buffer); } return 1; }
答案 0 :(得分:0)
空终止符由\0
而非0
note_buffer[note_length] = 0;
应该是
note_buffer[note_length] = '\0';
答案 1 :(得分:0)
请记住,在C中,数组的索引是从0到(array-1的长度)
这一行:
char* note_buffer;
声明一个指向字符的初始化指针。 I.E.它的值取决于该位置当前存储器中的垃圾。这样的操作如访问垃圾“点”的位置将是未定义的行为并且可能导致seg故障事件。
强烈建议,在这一行之后:
char* note_buffer;
插入以下内容:(包括检查malloc()
失败:
note_buffer = malloc( note_length+1 );
if( !note_buffer )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
注意:如果+1
调用malloc()
以下行,则无法使用note_buffer[note_length] = 0;
:
0
将设置一个超出分配区域结尾的字节。这将是未定义的行为,并可能导致seg故障事件
此外,note_buffer[note_length] = '\0';
的位模式为0x000000000000000000000000,而'\ 0'的位模式为0x00000000。隐式转换功能将在此实例中保存您,但不依赖于该功能,而是正确编码文字。所以该行应该是:
perror()
注意:stderr
输出所附文本字符串以及操作系统认为错误发生的原因{{1}},这是应输出所有错误消息的地方。