如何使用malloc实现getline

时间:2015-05-10 20:01:06

标签: c pointers malloc getline

我试图向http-fs-wrapper添加getline支持,但我遇到了一些malloc问题。

ssize_t _intercept_getdelim(int fd, char **lineptr, size_t *n, int delim)
{
    intercept_t *obj = intercept[fd];
    int counter;
    size_t nc = sizeof(char);

    counter = -1;
    while (obj->offset < obj->size)
    {
        ++counter;
        if (*lineptr) {
            *lineptr = realloc(*lineptr, (counter + 2) * nc);
        }
        else {
            *lineptr = malloc(nc);
        }
        _intercept_read(fd, lineptr[counter], nc);
        if (*lineptr[counter] == delim)
        {
           break;
        }
    }
    *n = counter ? counter + 1 : counter;
    *lineptr[counter + 2] = '\0';
    // Why do we need a *n when the return value is the same??
    return *n;
}

以下是_intercept_read的相关部分:

size_t _intercept_read(int fd, void *buf, size_t count)
{
    memcpy(buf, obj->ra_buf+bo, count);

当我在gdb中逐步执行此操作时,第二次迭代会抛出一个SIGSEGV(来自memcpy - 它不是结尾\0,它仍然在循环中)。我也不太了解*n / getline的{​​{1}}与返回值之间的区别。

1 个答案:

答案 0 :(得分:0)

这有效:

ssize_t _intercept_getdelim(int fd, char **lineptr, size_t *n, int delim)
{
    intercept_t *obj = intercept[fd];
    int counter = -1;
    char *c, *newbuf;

    *n = 1;
    *lineptr = malloc(*n);
    while (obj->offset < obj->size)
    {
        ++counter;
        if (counter >= *n)
        {
            if ((newbuf = realloc(*lineptr, *n  << 1)))
            {
                *n = *n << 1;
                *lineptr = newbuf;
            }
            else
            {
                return -1;
            }

        }
        c = *lineptr + counter;
        _intercept_read(fd, c, nc);
        if (*c == delim)
        {
           break;
        }
    }
    if (counter > -1)
    {
        *(*lineptr + ++counter) = '\0';
    }
    return counter;
}