【问题标题】:Redundant character is being added to one of the buffers when using readv() linux system call使用 readv() linux 系统调用时,冗余字符被添加到缓冲区之一
【发布时间】:2012-02-21 20:01:54
【问题描述】:

我遇到了(可能)我无法解释的错误,如果有人可以,我会很高兴。

**我写了以下程序:

#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' 和 ']' 之间的白色方块。 为什么会发生这种奇怪的事情?

谢谢你..

【问题讨论】:

    标签: c gcc file-io operating-system linux-kernel


    【解决方案1】:

    没有添加额外的字符。您的程序中有两个错误。

    1. 您引用了TEST[5](即arr1[5]),它超出了arr1 数组的末尾。 C ararys 从零开始,因此唯一有效的值是:arr1[0]arr1[1]arr1[2]arr1[3]arr1[4]arr1[5] 是数组中的第六项,而不是第五
    2. 您打印了一个没有 nul 终止符的字符数组。 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】:

      首先,您查看的是 TEST[5],它是 5 缓冲区中的第六个字符,换句话说,此时它是完全随机的。

      其次,strlen(TEST) 依赖于 TEST 以零终止,readv() 不保证这一点。 6 的长度再次是随机的,因为它取决于缓冲区之外的内存。

      【讨论】:

        猜你喜欢
        • 2010-09-20
        • 1970-01-01
        • 2015-11-17
        • 1970-01-01
        • 2012-05-18
        • 2021-07-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多