【问题标题】:counting lines of input using memchr fails使用 memchr 计算输入行失败
【发布时间】:2018-09-25 22:34:11
【问题描述】:

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

#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("%d\n", ++c);
    return 0;
}

我是用 gcc 编译的,没有任何选项。

运行时,它给出的结果不稳定,与事实相差不远,但结果却是错误的。有时它会出现段错误。缓冲区大小越大,段错误就越频繁。

我做错了什么?

【问题讨论】:

  • 你应该开始放弃滥用goto

标签: c gcc segmentation-fault


【解决方案1】:

使用-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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    相关资源
    最近更新 更多