C - 使用 MEMCHR 计算输入行失败



我写了一个程序来计算stdin给出的输入行数:

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#define BUFF_SIZE  8192
#define RS  'n'
int
main(int argc, char **argv)
{
char buff[BUFF_SIZE];
ssize_t n;
char *r; 
int c = 0;
readchunk:
n = read(0, buff, BUFF_SIZE);
if (n<=0) goto end; // EOF
r=buff;
searchrs:
r = memchr(r, RS, n);
if(r!=NULL) {
c++;
if((r-buff)<n) {
++r;
goto searchrs;
}
}
goto readchunk;
end:
printf("%dn", ++c);
return 0;
}

我用 gcc 编译了它,没有选项。

运行时,它给出的结果不稳定,离真不远,但假。有时它会出现段错误。缓冲区大小越大,段错误的频率就越高。

我做错了什么?

使用-fsanitize=address构建程序并为其提供足够长的输入会产生:

==119818==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffedbba1500 at pc 0x7fc4d56fd574 bp 0x7ffedbb9f4a0 sp 0x7ffedbb9ec50
READ of size 8192 at 0x7ffedbba1500 thread T0
#0 0x7fc4d56fd573  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x40573)
#1 0x563fdf5f4b90 in main /tmp/t.c:23
#2 0x7fc4d533e2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
#3 0x563fdf5f49c9 in _start (/tmp/a.out+0x9c9)
Address 0x7ffedbba1500 is located in stack of thread T0 at offset 8224 in frame
#0 0x563fdf5f4ab9 in main /tmp/t.c:11
This frame has 1 object(s):
[32, 8224) 'buff' <== Memory access at offset 8224 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x40573)

第 23 行是对memchr的调用。

当你递增r时,你可能应该递减n

最新更新