подсчет строк ввода с использованием memchr не удался - PullRequest
0 голосов
/ 26 сентября 2018

Я написал программу для подсчета строк ввода, заданного 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("%d\n", ++c);
    return 0;
}

Я скомпилировал его с помощью gcc, без параметров.

При запуске он дает нестабильный результат, а недалеко от истины, но ложно.Иногда это segfaults.Чем больше размер буфера, тем чаще он выходит из строя.

Что я делаю не так?

1 Ответ

0 голосов
/ 26 сентября 2018

Сборка вашей программы с помощью -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.

...