Избыточный символ добавляется в один из буферов при использовании системного вызова readv () linux - PullRequest
1 голос
/ 22 февраля 2012

Я столкнулся с ошибкой (вероятно), которую я не могу объяснить, и я был бы счастлив, если бы кто-то смог.

** Я написал следующую программу:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/uio.h>
#include <string.h>


int main(int argc, char** argv)
{

   char arr1[5], arr2[5], arr3[5];
   struct iovec iov[3];
   ssize_t n;
   int fd, i;


    fd = open("/home/oz/Desktop/test", O_RDONLY);
    if (fd == -1)
    {
        perror("open error");
        return (1);
    }

    iov[0].iov_base = arr1;
    iov[1].iov_base = arr2;
    iov[2].iov_base = arr3;
    iov[0].iov_len = 5;
    iov[1].iov_len = 5;
    iov[2].iov_len = 5;

    n = readv(fd, iov, 3);
    if (n == -1)
    {
        perror("read error");
        return (1);
    }


    for (i = 0; i < 3; i++)
    {
        printf("Buffer %d  Content : [%s]\n", i, (char *)iov[i].iov_base);
    }


    // DEBUG - START
    printf("Total bytes read : %d\n", (int)n);
    char * TEST = iov[0].iov_base;
    printf("TEST LAST CHARACTER (int)= %d.\nTEST LENGTH = %d\n", TEST[5], (int)strlen(TEST));
    // DEBUG - END

    return 0;

}

Содержимое файла, из которого я прочитал (это однострочный текстовый файл): 123456789012345678901234567890

** Выход

Buffer 0  Content : [12345]
Buffer 1  Content : [67890]
Buffer 2  Content : [12345]
Total bytes read : 15
TEST LAST CHARACTER (int)= 127.
TEST LENGTH = 6

** Мой вопрос: Символ со значением ASCII 127 был добавлен в первый буфер по неизвестной причине. (В моем стандартном выводе я фактически вижу его как белый квадрат между «5» и «]» в первой строке вывода. Почему произошла эта странная вещь?

Спасибо ..

Ответы [ 2 ]

2 голосов
/ 22 февраля 2012

Никаких дополнительных символов не добавляется. В вашей программе две ошибки.

  1. Вы ссылаетесь на TEST[5] (то есть arr1[5]), который находится за концом массива arr1. Классы C основаны на нуле, поэтому единственные допустимые значения: arr1[0], arr1[1], arr1[2], arr1[3] и arr1[4]. arr1[5] - это шестая запись в массиве, а не пятая .
  2. Вы печатаете массив символов, который не имеет нулевого завершения. Строки C требуют завершающего нуля, который вы не предоставляете. Как следствие, система времени выполнения успешно печатает любые символы за пределами массива.

Внесите следующие изменения в вашу программу:

printf("Buffer %d  Content : [%5.5s]\n", i, (char *)iov[i].iov_base);
...
printf("TEST LAST CHARACTER (int)= %d.\nTEST LENGTH = %d\n", TEST[4], 5);
2 голосов
/ 22 февраля 2012

Во-первых, вы смотрите на TEST [5], который является шестым символом в буфере из 5, другими словами, в этот момент он абсолютно случайный.

Во-вторых, strlen(TEST) зависит от того, завершается ли TEST нулем, что readv() не гарантирует. Длина 6 снова случайна, так как она зависит от памяти вне ваших буферов.

...