如何防止C/C++中的缓冲区溢出?
我使用以下代码将标准输出重定向到管道,然后将所有数据从管道读取到缓冲区。我有两个问题:
第一个问题:当我发送一个大于管道的 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 am using the following code to redirect stdout to a pipe, then read all the data from the pipe to a buffer. I have 2 problems:
first problem: when i send a string (after redirection) bigger then the pipe's BUFF_SIZE, the program stops responding (deadlock or something).
second problem: when i try to read from a pipe before something was sent to stdout. I get the same response, the program stops responding - _read command stuck's ...
The issue is that i don't know the amount of data that will be sent to the pipe after the redirection.
The first problem, i don't know how to handle and i'll be glad for help. The second problem i solved by a simple workaround, right after the redirection i print space character to stdout. but i guess that this solution is not the correct one ...
#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);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的问题是您正在使用阻塞 I/O 调用,而管道的两端都连接到同一进程。如果您不知道会有多少数据,那么这只是等待发生的死锁情况。
printf 是一个阻塞调用,这意味着它不会返回,直到所有数据都写入输出设备(本例中为管道),或者发出写入错误信号(例如,管道的另一端是封闭的)。
_read
的工作原理类似。仅当它具有完整的数据缓冲区或知道已到达输入末尾(可以通过关闭管道的写入端来发出信号)时,它才返回。解决这个问题的唯一方法是
printf
的代码,这是不可行的),或者Your problem is that you are using blocking I/O calls, while both ends of the pipe are connected to the same process. If you don't know how much data there will be, this is just a deadlock situation waiting to happen.
printf
is a blocking call, which means that it will not return until all data has been written to the output device (the pipe in this case), or until a write error is signalled (for example, the other end of the pipe is closed)._read
works similarly. It only returns when it has a full buffer worth of data or it knows that the end of the input has been reached (which can be signalled by closing the write-end of the pipe).The only ways around this are
printf
), or管道是单向的。 IE。您可以向管道 (x) 写入数据,也可以从中读取数据。
要模拟管道,请尝试以下操作(以下是 C,而不是 C++):
[编辑] 顺便说一句,您的代码不会溢出缓冲区。它与缓冲区溢出的唯一关系是您正在读入静态分配的数组...如果您
read()
超过sizeof buffer
元素,那么您将运行陷入问题。Pipes are unidirectional. Ie. you can either write to a pipe (x)or you can read from it.
To simulate a pipeline, try the following (the below is C, not C++):
[edit] By the way, your code does not overflow a buffer. Its only relation to buffer overflow is that you're reading into a statically allocated array...if you
read()
more thansizeof buffer
elements, then you'll run into problems.如果您不希望在这种情况下读取或写入被阻止,则必须使用非阻塞 I/O。
You must use non-blocking I/O if you don't want read or write to be blocked in this case.