1

我有点卡在一些代码上。我必须使用getToto()通常返回 a的方法的返回类型std::string,但在一种情况下它会返回false(它是我必须使用的库的一部分,我无法修改它)。我知道这相当于一个空指针。但是我找不到合适的方法来捕捉它!

测试.cpp

static std::string getToto(){
 char buffer[1024];
 if ( CTX_Get_Env(buffer, "Toto", 1024) )
    return false;
 return buffer;
}

如果我尝试

const char* returned = Test::getToto().c_str();
if (returned==NULL){
    std::cout<< "null pointer"<<std::endl;
}

运行时出现错误

在抛出 'std::logic_error' 的实例后调用终止

what(): basic_string::_S_construct NULL 无效

抱歉,我的 C++ 水平相当低。

4

3 回答 3

3

这取决于。是返回逻辑的空字符串部分,还是异常情况。

如果它不应该发生,你应该抛出一个错误。

如果字符串可以为空,则应该只返回一个空字符串:

 return std::string();

它按原样编译的原因是它false被解释为0,即NULL,它可以是 a char*,因此尝试从它构造一个字符串。但是,std::stringNULL指针构造一个是无效的,这就是你得到异常的原因。

这是我的编码方式:

static std::string getToto(){
   char buffer[1024];
   if ( CTX_Get_Env(buffer, "Toto", 1024) )
      throw InvalidDataInBufferException();
   return buffer;
}

如果字符串不应该为空,或者

static std::string getToto(){
   char buffer[1024];
   if ( CTX_Get_Env(buffer, "Toto", 1024) )
      return std::string();
   return buffer;
}

如果字符串为空是可以的。

于 2012-11-20T16:23:23.803 回答
3

隐式std::string(const char*)构造函数正在初始化false,它被解释为空指针。std::string标准不允许从空指针构造一个。在您的平台上,这会导致引发异常。如果无法修改函数,可以将函数调用放在 try 块内,但请注意,这绝不保证在其他平台上也能正常工作

try {
  std::string returned = Test::getToto().c_str();
  const char* c = returned.c_str();
} catch(...) {
  // handle the error
}

注意 1std::string :由于如果 an从空指针初始化,则不需要实现引发异常,因此调用该getToto()函数可能会导致未定义的行为。这些try-catch块仅在您的实现引发异常时才有帮助,因此不是可移植的解决方案。这也意味着getToto()应该避免调用未定义行为的库函数。

注意2:异常隐藏了另一个错误,这里:

const char* returned = Test::getToto().c_str();

Test::getToto()返回一个您没有分配的临时字符串。你的returned指针悬空。在我的代码示例中,我将 return 分配给 an std::string然后获取指向其内部 char 数据的指针。

于 2012-11-20T16:25:05.687 回答
0

您应该明白,在 getToto() 真正返回之前,您遇到了异常。没有办法从返回字符串的函数中执行“return false”并且不会出现异常。这只是一个错误。您可以使用 try/catch 块覆盖它,如下所示:

const char* returned = NULL;
try{
    returned = Test::getToto().c_str();
}catch(std::exception& e){
    std::cout << "null pointer" << std::endl;
}

但这仍然是一件坏事。

于 2012-11-20T19:42:45.687 回答