How return a std::string from C's “getcwd” function

后端 未结 7 528
我寻月下人不归
我寻月下人不归 2021-01-20 07:35

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*, be

7条回答
  •  有刺的猬
    2021-01-20 08:00

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

    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.

提交回复
热议问题