c ++如何处理返回NULL或std :: string的方法?

Posted

技术标签:

【中文标题】c ++如何处理返回NULL或std :: string的方法?【英文标题】:c++ how to deal with method returning either NULL or std::string? 【发布时间】:2012-11-20 16:21:06 【问题描述】:

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

Test.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++ 水平相当低。

【问题讨论】:

如果 getToto 是您无法修改的库的一部分,那么您能做的最好的事情就是向您的库供应商提交错误报告。 【参考方案1】:

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

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

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

 return std::string();

它按原样编译的原因是false被解释为0,也就是NULL,也可以是char*,所以试图从中构造一个字符串。但是,从 NULL 指针构造 std::string 是无效的,这就是您遇到异常的原因。

这是我的编码方式:

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;

如果字符串为空也可以。

【讨论】:

@user1839362 好的。您是否尝试设置 Toto 环境变量?【参考方案2】:

隐式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

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

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

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

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

【讨论】:

我没有投反对票,但答案导致指针悬空。 @Mat 啊,没看到那部分。 临时的std::string 将被销毁,留下returned 作为悬空指针。 @hmjd 是的,看到并修复了答案。谢谢。 我原以为这是未定义的行为。如果标准未指定抛出异常,则鉴于getToto() 函数不可修改且永远损坏,因此没有可移植的方法来解决此问题。【参考方案3】:

您应该明白,在 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;

但这仍然是一件坏事。

【讨论】:

以上是关于c ++如何处理返回NULL或std :: string的方法?的主要内容,如果未能解决你的问题,请参考以下文章

c++ new 对象问题

前端如何处理内存泄漏

前台如何处理后台返回的json数据

C ++自定义控制台类 - 如何处理“<

服务器返回<null>值 iOS 端如何处理

如何处理可能返回 null 并生成 System.NullReferenceException 的方法