c-何时调用_pclose



我有一个函数,在其中我多次调用_open。

如果_popen返回NULL,我是否需要在函数返回之前调用_pclose

我已经标记了3个我认为可能需要调用_pclose的位置。

我必须在以下哪个位置拨打_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,则不会释放FILE对象占用的内存。更糟糕的是,还有外部可见的后果。由popen创建的子进程可能会徘徊。当您使用popen时,会使用fork创建一个流程。相应的CCD_ 12可能直到调用CCD_。(我相信这是一个典型的、显而易见的实现,这也是我为其他编程语言实现类似popen的函数的方式。)

尽管Win32没有forkwait,但在Microsoft C库的_popen中可能存在类似的资源问题。FILE管道句柄可能有一个进程的内部Win32句柄,在调用_pclose之前,该进程不受CloseHandle的约束。加上其他资源,如与该进程通信的Win32管道。如果你不关闭管道,那么你就会泄漏这些资源。

关于传递空指针。这是对原始POSIX函数的否定。如果在空指针上调用pclose,则不会定义该行为。POSIX表示"[i]如果pclose()的参数流不是popen()创建的流的指针,则pclose的结果是未定义的。"(空指针不是指向流的指针(即使它是由popen返回的)。

Microsoft允许使用空指针调用_pclose。MSDN中对此进行了说明,其行为是_pclose返回-1并将errno伪变量设置为EINVAL

如果您想要移植基于这些函数的代码,则需要考虑这一点。

相关内容

  • 没有找到相关文章

最新更新