Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何从C';s";getcwd";功能_C++_Memory Leaks_Cross Platform_Getcwd - Fatal编程技术网

C++ 如何从C';s";getcwd";功能

C++ 如何从C';s";getcwd";功能,c++,memory-leaks,cross-platform,getcwd,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; } 更新2:如果没有Boost或Qt,最常见的东西可能会变得冗长(请参阅公认的答案)您需要检查cwd是否为N

很抱歉一直在讨论这个问题,但我正在努力学习:)。这有什么好处吗?是的,我关心内存泄漏。我找不到一个合适的方法来预分配char*,因为似乎没有跨平台的方法

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

更新2:如果没有Boost或Qt,最常见的东西可能会变得冗长(请参阅公认的答案)

您需要检查cwd是否为NULL。然后它将在Mac、Windows和Linux上工作。但是,它不符合POSIX


编辑:perror不退出程序,因此您应该退出、抛出异常或执行某些操作。

这将在Windows和Linux上运行,因为它们都支持
getcwd
buf
参数为NULL时的自动分配行为。但是,请注意,这种行为不是标准的,因此在更深奥的平台上可能会出现问题

但是,您可以不依赖此行为来执行此操作:

const string getcwd()
{
    size_t buf_size = 1024;
    char* buf = NULL;
    char* r_buf;

    do {
      buf = static_cast<char*>(realloc(buf, buf_size));
      r_buf = getcwd(buf, buf_size);
      if (!r_buf) {
        if (errno == ERANGE) {
          buf_size *= 2;
        } else {
          free(buf);
          throw std::runtime_error(); 
          // Or some other error handling code
        }
      }
    } while (!r_buf);

    string str(buf);
    free(buf);
    return str;
}
const字符串getcwd()
{
大小为1024;
char*buf=NULL;
char*r_buf;
做{
buf=静态铸件(realloc(buf,buf尺寸));
r_buf=getcwd(buf,buf_大小);
如果(!r_buf){
if(errno==ERANGE){
buf_尺寸*=2;
}否则{
免费(buf);
抛出std::runtime_error();
//或者其他一些错误处理代码
}
}
}而(!r_buf);
字符串str(buf);
免费(buf);
返回str;
}
上面的代码以1024缓冲区大小开始,然后,如果
getcwd
抱怨缓冲区太小,它会将大小加倍并重试,然后重复,直到有足够大的缓冲区并成功


注意,第一个参数为NULL的调用
realloc
malloc

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

类似的东西可能会起作用(注意:没有经过测试,只是从头开始编写,当然可以改进):

string getcwd()
{
常量大小\u t chunkSize=255;
const int maxChunks=10240;//当前路径的2550 kib就足够了
char stackBuffer[chunkSize];//正常情况下的堆栈缓冲区
if(getcwd(stackBuffer,sizeof(stackBuffer))!=NULL)
返回堆栈缓冲区;
if(errno!=ERANGE)
{
//这不是语言,所以我们不知道如何处理
抛出std::runtime_错误(“无法确定当前路径”);
//当然,您可以选择不同的错误报告方法
}
//好的,堆栈缓冲区不够长;回退到堆分配

对于(int chunks=2;chunks您不能将空指针传递给
std::string
的构造函数,因此必须检查
getcwd()
返回的缓冲区指针是否为空。此外,传递给
getcwd()
的缓冲区指针


你应该使用ISO C++兼容版本<代码> .GETCWD < /Cord>我认为,返回<代码> const字符串没有意义,并且应该使用<代码>免费< /C> >(至少根据MSDN):


当然,您还应该检查
\u getcwd()
是否返回空值。

这怎么样?它很短,异常安全,并且不会泄漏

std::string getcwd() {
    std::string result(1024,'\0');
    while( getcwd(&result[0], result.size()) == 0) {
        if( errno != ERANGE ) {
          throw std::runtime_error(strerror(errno));
        }
        result.resize(result.size()*2);
    }   
    result.resize(result.find('\0'));
    return result;
}
当“字符串构造函数”为您完成所有操作时:

#include <stdio.h>  // defines FILENAME_MAX
#include <unistd.h> // for getcwd()

std::string GetCurrentWorkingDir()
{
    std::string cwd("\0",FILENAME_MAX+1);
    return getcwd(&cwd[0],cwd.capacity());
}
\include//定义文件名\u MAX
#包含//用于getcwd()
std::字符串GetCurrentWorkingDir()
{
std::字符串cwd(“\0”,文件名\u MAX+1);
返回getcwd(&cwd[0],cwd.capacity());
}

查看rubenvb的相关内容。什么是
CAKE_getcwd
?Google什么也找不到。普通的
getcwd
在Solaris上无法像您所希望的那样工作。尽管当您向它传递空指针时它会分配内存,但它分配的内存量完全基于第二个
getcwd
参数,而不是它所使用的字符串长度想要返回。因此,在您的示例中,它将分配零字节(或者简单地使用EINVAL失败)。CAKE_getcwd是我为Windows上的纯getcwd vs_getcwd的弃用警告定义的变通方法。Fixed我个人更喜欢信息丰富的标题,而不仅仅是“主题问题”…我们知道这是一个问题,因为标签,我们知道它是什么主题,所以细节很好:)固定的标题和Wrand将试图在未来的GETCWWD中更具描述性。但是,如果你看前面的问题,Ruube用IFDEF来覆盖这个问题。@马修:对不起,我的意思是说ISO C++的一致性。得到了,从MSDN复制粘贴:我认为POSIX标准在这里是愚蠢的,因为没有安全的方法。ely分配一个保证足够大的字符*>:s@ruben,我不同意。_PC_PATH_MAX是推荐的方法。值得注意的是,getcwd永远不会出现缓冲区溢出,因为您会传递它的大小。如果缓冲区太小,它最多会给您一个错误。MSDN在POSIX上不是一个可靠的来源。从未说过任何关于t的事情他需要成为POSIX。我在这里放弃了POSIX的完全兼容性,并且很高兴:)@ruben,你说“POSIX标准在这里很愚蠢”。我指出的是,如果它只需要在POSIX上工作,那么有一个推荐的解决方案。自然地,跨平台工作会增加复杂性。我理解,并且对我的顽固决定感到遗憾“没有增压或Qt"为了让我的程序小巧美观。谢谢。如果你想让它符合POSIX标准并处理任意路径长度,这就是你必须要做的。如果你想让它更短,你必须放弃这两个要求中的一个。好吧,这就是我把POSIX抛到一边的地方:)你可以自由地这样做,但因为重点是你的问题似乎有点矛盾
string getcwd()
{
    char* a_cwd = _getcwd(NULL, 0);
    string s_cwd(a_cwd);
    free(a_cwd);
    return s_cwd;
}
std::string getcwd() {
    std::string result(1024,'\0');
    while( getcwd(&result[0], result.size()) == 0) {
        if( errno != ERANGE ) {
          throw std::runtime_error(strerror(errno));
        }
        result.resize(result.size()*2);
    }   
    result.resize(result.find('\0'));
    return result;
}
#include <stdio.h>  // defines FILENAME_MAX
#include <unistd.h> // for getcwd()

std::string GetCurrentWorkingDir()
{
    std::string cwd("\0",FILENAME_MAX+1);
    return getcwd(&cwd[0],cwd.capacity());
}