如何从C的“getcwd”返回std :: string功能 [英] How return a std::string from C's "getcwd" function

查看:265
本文介绍了如何从C的“getcwd”返回std :: string功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对不起,继续打击这个,但我想学习:)。这是什么好吗?是的,我关心内存泄漏。我找不到一个预先分配char *的方式,因为似乎没有跨平台的方式。

Sorry to keep hammering on this, but I'm trying to learn :). Is this any good? And yes, I care about memory leaks. I can't find a decent way of preallocating the char*, because there simply seems to be no cross-platform way.

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

UPDATE2:没有Boost或Qt,最常见的东西可以长(请参阅接受的答案)

UPDATE2: without Boost or Qt, the most common stuff can get long-winded (see accepted answer)

推荐答案

如果您想保持标准, getcwd 不需要做任何事情,如果你传递给它一个NULL;你应该在堆栈上分配一个足够大的大多数情况下使用的缓冲区(比如说255个字符),但要准备好让 getcwd 失败 errno == ERANGE ;在这种情况下,你应该分配一个更大的缓冲区,如果必要,增加它的大小。

If you want to remain standard, getcwd isn't required to do anything if you pass to it a NULL; you should instead allocate on the stack a buffer that is "large enough" for most occasions (say, 255 characters), but be prepared for the occasion in which getcwd may fail with errno==ERANGE; in that case you should allocate dinamically a bigger buffer, and increase its size if necessary.

这样的东西可以工作(注意:没有测试,必须改进):

Something like this could work (notice: not tested, just written by scratch, can be surely improved):

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");
}

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

By the way, in your code there's a very wrong thing: you are trying to dellocate a_cwd (which presumably, in the nonstandard extension, is allocated with malloc or with some other memory allocation function, since getcwd is thought for C) with delete: you absolutely shouldn't do that, keep in mind that each allocation method has its deallocation counterpart, and they must not be mismatched.

这篇关于如何从C的“getcwd”返回std :: string功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆