什么时候调用_pclose?

时间:2015-12-03 19:03:31

标签: c windows pipe popen 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;
}

2 个答案:

答案 0 :(得分:1)

简单:如果您可以打开它但不再需要它,请关闭管道。所以:

  public void CrashScreen(){
        System.out.println("hi");
          Intent intent = new Intent(gameView.getContext(), Crash.class);
          startActivity(intent);

    }

答案 1 :(得分:1)

如果您使用popen成功创建了一个管道但未调用pclose,则FILE对象占用的内存不会被释放。更糟糕的是,有外部可见的后果。由popen创建的子进程可能会四处流淌。当您popen时,会使用fork创建流程。在调用waitpid之前,相应的pclose可能不会发生。 (我相信这是一个典型的,明显的实现,它是我为其他编程语言实现类似popen的函数的方式。)

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

关于传递空指针。这是原始POSIX功能的禁忌。如果在空指针上调用pclose,则不定义行为。 POSIX说" [i] f pclose()的参数流不是指向popen()创建的流的指针,pclose()的结果是未定义的。" (空指针不是指向流的指针,即使它是由popen返回的)。

Microsoft允许使用空指针调用_pclose。这是documented in MSDN,行为是_pclose返回-1并将errno伪变量设置为EINVAL

如果您想要移植基于这些功能的代码,可以考虑这一点。

相关问题