gpt4 book ai didi

c++ - 如何防止C/C++中的缓冲区溢出?

转载 作者:太空狗 更新时间:2023-10-29 21:50:59 26 4
gpt4 key购买 nike

我正在使用以下代码将标准输出重定向到管道,然后将所有数据从管道读取到缓冲区。我有两个问题:

第一个问题:当我发送一个大于管道的 BUFF_SIZE 的字符串(重定向后)时,程序停止响应(死锁或其他问题)。

第二个问题: 当我尝试在将某些内容发送到标准输出之前从管道读取数据时。我得到相同的响应,程序停止响应 - _read 命令卡住的 ...

问题是我不知道重定向后将发送到管道的数据量。

第一个问题,我不知道如何处理,我很乐意寻求帮助。我通过一个简单的解决方法解决了第二个问题,在重定向之后我将空格字符打印到标准输出。但我想这个解决方案不是正确的......

#include <fcntl.h>
#include <io.h>
#include <iostream>

#define READ 0
#define WRITE 1
#define BUFF_SIZE 5

using namespace std;

int main()
{

int stdout_pipe[2];
int saved_stdout;

saved_stdout = _dup(_fileno(stdout)); // save stdout

if(_pipe(stdout_pipe,BUFF_SIZE, O_TEXT) != 0 ) // make a pipe
{
exit(1);
}

fflush( stdout );

if(_dup2(stdout_pipe[1], _fileno(stdout)) != 0 ) //redirect stdout to the pipe
{
exit(1);
}

ios::sync_with_stdio();
setvbuf( stdout, NULL, _IONBF, 0 );

//anything sent to stdout goes now to the pipe
//printf(" ");//workaround for the second problem

printf("123456");//first problem

char buffer[BUFF_SIZE] = {0};
int nOutRead = 0;
nOutRead = _read(stdout_pipe[READ], buffer, BUFF_SIZE); //second problem
buffer[nOutRead] = '\0';

// reconnect stdout

if (_dup2(saved_stdout, _fileno(stdout)) != 0 )
{
exit(1);
}
ios::sync_with_stdio();

printf("buffer: %s\n", buffer);
}

最佳答案

您的问题是您正在使用阻塞 I/O 调用,而管道的两端都连接到同一个进程。如果您不知道会有多少数据,这只是等待发生的死锁情况。

printf 是一个阻塞调用,这意味着它不会返回,直到所有数据都已写入输出设备(在本例中为管道),或者直到发出写入错误信号(对于例如,管道的另一端是封闭的)。
_read 的工作方式类似。它仅在具有完整缓冲区的数据或知道已到达输入末尾时返回(可以通过关闭管道的写入端来发出信号)。

解决这个问题的唯一方法是

  • 使用非阻塞 I/O(如果您无法访问调用 printf 的代码,这是不可行的),或者
  • 确保读写发生在不同的进程或线程中,或者
  • 使用临时文件进行缓冲,而不是管道缓冲区。

关于c++ - 如何防止C/C++中的缓冲区溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4667890/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com