如何从C的"getcwd"函数返回一个std :: string

rub*_*nvb 3 c++ memory-leaks cross-platform getcwd

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

const string getcwd()
{
    char* a_cwd = getcwd(NULL,0);
    string s_cwd(a_cwd);
    free(a_cwd);
    return s_cwd;
}
Run Code Online (Sandbox Code Playgroud)

UPDATE2:没有Boost或Qt,最常见的东西可以啰嗦(见接受的答案)

Mat*_*lia 7

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

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

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");
}
Run Code Online (Sandbox Code Playgroud)

顺便说一下,在你的代码中有一个非常错误的东西:你试图dellocate a_cwd(可能是在非标准扩展中,分配了malloc或其他一些内存分配函数,因为getcwd被认为是C)delete:你绝对不应该这样做,请记住每个分配方法都有其释放对应物,并且它们不能不匹配.