簡體   English   中英

無法在以null結尾的字符串上運行printf()

[英]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()+1malloc()下行:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM