很抱歉继续对此进行抨击,但我正在努力学习:)。这有什么好处吗?是的,我关心内存泄漏。我找不到预分配 char* 的好方法,因为似乎没有跨平台的方法。

const string getcwd()
{
    char* a_cwd = getcwd(NULL,0);
    string s_cwd(a_cwd);
    free(a_cwd);
    return s_cwd;
}

UPDATE2:如果没有 Boost 或 Qt,最常见的东西会变得冗长(请参阅已接受的答案)

最佳答案

如果你想保持标准,getcwd 不需要做任何事情,如果你传递给它一个 NULL;您应该在堆栈上分配一个“足够大”的缓冲区,在大多数情况下(例如,255 个字符),但要为 getcwd 可能因 errno==ERANGE 而失败的情况做好准备;在这种情况下,您应该动态分配更大的缓冲区,并在必要时增加其大小。

像这样的东西可以工作(注意:未经测试,只是从头开始编写,肯定可以改进):

string getcwd()
{
    const size_t chunkSize=255;
    const int maxChunks=10240; // 2550 KiBs of current path are more than enough

    char stackBuffer[chunkSize]; // Stack buffer for the "normal" case
    if(getcwd(stackBuffer,sizeof(stackBuffer))!=NULL)
        return stackBuffer;
    if(errno!=ERANGE)
    {
        // It's not ERANGE, so we don't know how to handle it
        throw std::runtime_error("Cannot determine the current path.");
        // Of course you may choose a different error reporting method
    }
    // Ok, the stack buffer isn't long enough; fallback to heap allocation
    for(int chunks=2; chunks<maxChunks ; chunks++)
    {
        // With boost use scoped_ptr; in C++0x, use unique_ptr
        // If you want to be less C++ but more efficient you may want to use realloc
        std::auto_ptr<char> cwd(new char[chunkSize*chunks]);
        if(getcwd(cwd.get(),chunkSize*chunks)!=NULL)
            return cwd.get();
        if(errno!=ERANGE)
        {
            // It's not ERANGE, so we don't know how to handle it
            throw std::runtime_error("Cannot determine the current path.");
            // Of course you may choose a different error reporting method
        }
    }
    throw std::runtime_error("Cannot determine the current path; the path is apparently unreasonably long");
}

顺便说一句,在您的代码中有一个非常错误的事情:您正在尝试使用 delete 来 delocate a_cwd (大概在非标准扩展中,它是用 malloc 或其他一些内存分配函数分配的,因为 getcwd 被认为用于 C)您绝对不应该这样做,请记住,每个分配方法都有其对应的解除分配方法,并且它们不能不匹配。

关于c++ - 如何从 C 的 "getcwd"函数返回 std::string,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2869594/

10-12 23:09