Can';t在以null结尾的字符串上运行printf()

Can';t在以null结尾的字符串上运行printf(),c,gdb,C,Gdb,由于某种原因,当我传递以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/fro

由于某种原因,当我传递以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) λsudo gdb-q注释搜索 正在从notesearch读取符号…完成。 (gdb)中断53 断点1位于0x400b32:文件notesearch.c,第53行。 (gdb)运行 启动程序:/home/frosty/hack/chapter_2/code/notesearch [调试]用户标识:0 [调试]文件描述符:3 断点1,打印注释(fd=3,uid=0,searchstring=0x7fff3daf7fc0“”) 在notesearch.c:53 53 printf(“%s\n”,注释\u缓冲区); (gdb)x/8xb注释\U缓冲区 0x7feb5a997168:0x68 0x65 0x6c 0x6c 0x6f 0x0a 0x00 0x00 (gdb)x/s注释缓冲区 0x7feb5a997168:“您好\n” (gdb)下一步 程序接收信号SIGSEGV,分段故障。 _dl_fixup(l=,reloc_arg=) 在../elf/dl运行时。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); 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; } 整数打印注释(整数fd、整数uid、字符*搜索字符串){ int note_length=查找用户注释(fd,uid); 如果(注意长度==-1) 返回0;//文件结束 字符*注释\缓冲区; 读取(fd、注释缓冲区、注释长度); 注意\u缓冲区[注意\u长度]=0;//空终止符字节 if(搜索注释(注释缓冲区,搜索字符串)){ printf(“%s\n”,注释\u缓冲区); } 返回1; }
空终止符由
\0
0

note\u buffer[note\u length]=0

应该是


note_buffer[note_length]='\0'

空终止符由
\0
0

note\u buffer[note\u length]=0

应该是


note_buffer[note_length]='\0'

请记住,在C中,数组的索引从0到(数组长度-1)

这一行:

char* note_buffer;
声明指向字符的初始化指针。也就是说,它的值取决于该位置的内存中当前有哪些垃圾。访问垃圾“点”的位置是未定义的行为,可能导致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

note_buffer[note_length] = 0;
将设置一个字节,该字节超过分配区域的末尾。这将是未定义的行为,可能导致seg故障事件

另外,
0
具有位模式0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

note_buffer[note_length] = '\0';

注意:
peror()
输出随附的文本字符串以及操作系统认为错误发生在
stderr
上的原因,这是所有错误消息应该输出的地方。

请记住,在C中,数组的索引范围是从0到(数组长度-1)

这一行:

char* note_buffer;
声明指向字符的初始化指针。即,其值取决于该位置内存中当前存在的垃圾。访问垃圾“点”的位置等操作将是未定义的行为,并可能导致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

note_buffer[note_length] = 0;
将设置一个字节,该字节超过分配区域的末尾。这将是未定义的行为,可能导致seg故障事件

另外,
0
具有位模式0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

note_buffer[note_length] = '\0';

注意:
perror()
输出随附的文本字符串以及操作系统认为错误发生在
stderr
上的原因,这是所有错误消息应该输出的地方。

校对可能与read()系统调用有关。将此行替换为:
read(fd,Note\u buffer,Note\u length);
(fd,¬e\u buffer,note\u length);
另外,我不知道该如何工作。
¬e\u buffer
将是指向字符指针的指针,
read()
只要求字符pointer@TimothySamson“read()只要求一个字符指针”-->
read()
需要一个指向有效内存的指针。可能与read()有关系统调用。将此行替换为:
read(fd,note\u buffer,note\u length);
read(fd,¬e\u buffer,note\u length);
另外,我不知道这是如何工作的。
note\u buffer
将是指向字符指针的指针,
read()
只要求字符pointer@TimothySamson“read()只要求一个字符指针”-->
read()
需要一个指向有效内存的指针。您有
char*note\u buffer;
,但从未分配内存。因此,当您使用它时,您将信息放入内存中,但不知道在哪里。要么先分配内存,要么使用char数组。@antoh尽管如此,我还是有点搞不清楚它为什么工作。如果您查看我的gdb输出,
read()
工作正常,可以读取预期的字符串。是因为它位于内存中的另一个区域(而不是堆)中,而printf无法读取内存中的特定区域吗?“我有点搞不懂它为什么工作”-->Code违反了规则,使用未初始化的note_buffer编写。C不需要合理的结果-欢迎使用未定义行为(Undefined Behavior,UB)。@TimothySamson它不起作用。它看起来起作用了,但实际上没有。仅仅因为你看到了你所期望的,并不意味着它起作用