当我尝试使用 write (man 2 write) 函数时,为什么这段代码会冻结?

Why this code freezes, when i'm trying to use write (man 2 write) function?

我正在尝试编写测试,其中一些数据应该从文件描述符中读取,所以我正在使用 dup 和管道函数来检查它。

 int main()
{
    char    *line;
    int     out;
    int     p[2];
    char    *str;
    int     len = 50;

    str = (char *)malloc(235436);
    for (int i = 0; i < 235436; ++i)
    {
        str[i]='h';
    }
    out = dup(1);
    pipe(p);
    dup2(p[1], 1);

    write(1, str, strlen(str)); //freezes there. malloc alocates memory, i've checked this with debuger
    close(p[1]);
    dup2(out, 1);
    get_next_line(p[0], &line);


}

出于某种原因,尽管这段代码的功能完全相同,但它可以完美运行。

str = (char *)malloc(1000 * 1000);
    *str = '[=11=]';
    while (len--)
        strcat(str, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur in leo dignissim, gravida leo id, imperdiet urna. Aliquam magna nunc, maximus quis eleifend et, scelerisque non dolor. Suspendisse augue augue, tempus");
    out = dup(1);
    pipe(p);
    dup2(p[1], 1);

    if (str)
        write(1, str, strlen(str));
    close(p[1]);
    dup2(out, 1);
    get_next_line(p[0], &line);

(假设您解决了 strlen 问题 - 即 write(1, str, 235436)

您正在写入管道。此管道未被读取。因此 write 将阻塞。

从管道中读取数据。

调用strlen函数有问题!

strlen(str)

因为你没有在字符串末尾设置终止符

在初始化循环后添加以下代码将解决问题:

str[235435]='[=11=]';

典型的 strlen 实现:

size_t strlen(char *s)
{
    size_t len = 0;
    while(*s++) len++;
    return len;
}

换句话说,它通过递增指向字符串开头的指针直到到达空终止符来确定字符串的长度。由于您的缓冲区只是字符 'h' 的一个块,没有空终止符,因此对其调用 strlen 具有未定义的行为。

你的第二个代码示例,你在调用 malloc 之后显式添加一个空终止符,然后使用 strcat 重复写入字符串没有这个问题,因为字符串文字是自动的空终止。

另外,don't cast the result of malloc 除非您的代码也需要与 C++ 兼容。

我在 linux 机器上使用管道。 根据这个 answer 我正在尝试读取比管道可以包含的更多字节。所以,在这种情况下,我需要创建文件并对其进行操作。

FILE *fptr;
fptr = fopen("buffer", "rb+");
if(fptr == NULL) //if file does not exist, create it
{
    fptr = fopen("buffer", "wb");
}