[英]Can't run printf() on a null-terminated string
當我因某種原因傳遞以null結尾的字符串時,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
note_buffer[note_length] = 0;
應該
note_buffer[note_length] = '\\0';
記住,在C中,數組的索引從0到(array-1的長度)
這一行:
char* note_buffer;
聲明一個初始化的指向字符的指針。 IE的值取決於該位置當前內存中的垃圾。 這樣的操作如訪問垃圾“點”的位置將是未定義的行為並且可能導致seg故障事件。
強烈建議,在這一行之后:
char* note_buffer;
插入以下內容:(包括檢查malloc()
失敗:
note_buffer = malloc( note_length+1 );
if( !note_buffer )
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc successful
注意:如果沒有調用malloc()
的+1
, malloc()
下行:
note_buffer[note_length] = 0;
將設置一個超過分配區域結尾的字節。 這將是未定義的行為,並可能導致seg故障事件
此外, 0
具有位模式0x000000000000000000000000,而'\\ 0'具有位模式0x00000000。 隱式轉換功能將在此實例中保存您,但不依賴於該功能,而是正確編碼文字。 所以該行應該是:
note_buffer[note_length] = '\0';
注意: perror()
輸出附帶的文本字符串和操作系統認為錯誤發生在stderr
,這是應該輸出所有錯誤消息的地方。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.