C 什么时候打电话?
我有一个函数,在这个函数中我调用了几次open 如果C 什么时候打电话?,c,windows,pipe,popen,pclose,C,Windows,Pipe,Popen,Pclose,我有一个函数,在这个函数中我调用了几次open 如果\u popen返回NULL我是否需要在函数返回之前调用\u pclose 我已经标记了3个我认为可能需要调用\u pclose的位置 我必须在这些位置中的哪个位置呼叫\u pclose bool theFunction() { FILE* pPipe; char buffer[1000]; if( (pPipe = _popen("dir", "rt")) == NULL ) { //locat
\u popen
返回NULL
我是否需要在函数返回之前调用\u pclose
我已经标记了3个我认为可能需要调用\u pclose
的位置
我必须在这些位置中的哪个位置呼叫\u pclose
bool theFunction()
{
FILE* pPipe;
char buffer[1000];
if( (pPipe = _popen("dir", "rt")) == NULL )
{
//location 1
_pclose(pPipe);
return false;
}
while(fgets(pipeBuffer, maxBufferSize, pPipe))
{
printf(pipeBuffer);
}
if( (pPipe = _popen("cls", "rt")) == NULL )
{
//location 2
_pclose(pPipe);
return false;
}
//location 3
_pclose(pPipe);
return true;
}
简单:如果可以打开但不再需要,请关闭管道。因此:
bool theFunction()
{
FILE* pPipe;
char buffer[1000];
if( (pPipe = _popen("dir", "rt")) == NULL )
{
return false;
}
while(fgets(pipeBuffer, maxBufferSize, pPipe))
{
printf(pipeBuffer);
}
// The fact that you have to close it here in the middle of nowhere
// should ring a bell that you need to think about separation of concern
_pclose(pPipe);
if( (pPipe = _popen("cls", "rt")) == NULL )
{
return false;
}
_pclose(pPipe);
return true;
}
如果成功使用
popen
创建管道,但未调用pclose
,则不会释放文件
对象占用的内存。更糟糕的是,还有外部可见的后果。由popen
创建的子进程可能会徘徊。当您使用popen
时,将使用fork
创建一个进程。在调用pclose
之前,可能不会发生相应的waitpid
。(我相信这是一个典型的、显而易见的实现,这也是我为其他编程语言实现类似popen的函数的方式。)
尽管Win32没有fork
和wait
,但Microsoft C库的\u popen
中可能存在类似的资源问题。文件
管道句柄可能有一个进程的内部Win32句柄,在调用\u pclose
之前,该句柄不受关闭句柄的约束。加上与该进程通信的其他资源,如Win32管道。如果你不关闭管道,那么你就泄漏了这些资源
关于传递空指针。这是对原始POSIX函数的否定。如果对空指针调用了pclose
,则不会定义该行为。POSIX说“[i]如果pclose()的参数流不是指向popen()创建的流的指针,则pclose()的结果是未定义的。”(空指针不是指向流的指针,即使它是由popen
返回的)
Microsoft允许使用空指针调用\u pclose
。这就是,\u pclose
返回-1并将errno
伪变量设置为EINVAL
如果你想输入基于这些函数的代码,这是要考虑的。
你不能关闭任何你不能打开的东西。请看第一个示例,您正试图关闭NULL
。请从\u pclose()
的角度来考虑这个问题。。。如果您传递了它NULL
,它怎么知道要关闭什么?好的,如果它看起来像一个糟糕的问题,那么很抱歉。虽然我知道pPipe在这些点上是Null
,但我对管道和这些命令还是新手。我这样问是因为我想确保在\u pclose
中没有其他东西被清理。谢谢你的快速回复。你查过手册了吗?是的,我已经阅读了手册页。为什么您第一次调用\u pclose
的位置是您的位置?因为此后您将覆盖pPipe
,因此您将丢失第一个管道的值,并且无法再关闭它。