防止核心转储使用空指针初始化字符串

Posted

技术标签:

【中文标题】防止核心转储使用空指针初始化字符串【英文标题】:Preventing Core Dump from initializing string with null pointer 【发布时间】:2015-12-06 19:25:35 【问题描述】:

在我的代码中,我有一个构造函数,它从包含char * 指针的结构中初始化std::string 变量。如果结构字段为空,我将在构造函数中使用 Visual Studio 2008 中止。

class Ingredient

  public:
    struct Static_Table
    
       char const * const title;
       char const * const category;
    ;
    Ingredient(const Static_Table& entry)
       : m_title(entry.title),
         m_category(entry.category)
     ; 
  private:
    std::string m_title;
    std::string m_variety;
;

如果我有一个成员为 NULL 的 Static_Table 实例,Ingredient 构造函数会爆炸

Ingredient::Static_Table test_data =

  /* Title */ "Pepperoni",
  /* Category */ 0, // Oops, forgot to put a string literal here.
;
Ingredient pepperoni(test_data); // This will cause Abort / Stack Dump

问题的基础是当char指针为空时行为未定义(来自basic_string definition on CppReference.com

用 s 指向的以空字符结尾的字符串的副本初始化内容来构造字符串。字符串的长度由第一个空字符确定。如果 s 未指向至少包含 Traits::length(s)+1 个 CharT 元素的数组,则行为未定义。

这可以通过简单的例子来验证:

#include <iostream>
#include <cstdlib>
#include <string>

int main(void)

    char const * const pointer = NULL;
    std::string test_string(pointer);
    std::cout << "Pointer: " << pointer << "\n";
    return EXIT_SUCCESS;

我的问题:

    有什么方法可以防止使用时中止/崩溃 构造函数的初始化列表? 为什么std::string不能像没有参数一样简单地构造空 给了?

工具信息:

在 Windows Vista 上使用 Visual Studio 2008。 使用 Cygwin 使用 G++ 3.4.4 编译的简单示例。

【问题讨论】:

您的结构是否有原因不包含 std::string 开头? 是的,我坚信常量数据,因此我可以将其放入只读内存中。 std::string 类型不能是常量数据(将放置在只读数据段中)。 std::string 需要在启动时特别初始化(相对于直接访问或使用字符/字符串文字复制)。 解决你的第二个问题,没有理由不能。然而,std::string 起源的 STL 非常强调效率,因此即使是在任何正确编写(是的,我的意见 ;) 程序中甚至都不需要的空指针检查也被避免了。 可能std::string 有一个引用成员,该引用成员通过传递给构造函数的指针的间接结果被初始化(没有Ul​​rich 提到的不必要的nullptr 检查)?然后它的存储可以被优化掉,虽然我不知道std::string的其他数据成员。 【参考方案1】:

对于您的第一个问题,您可以使用三元运算符来检查空指针:

Ingredient(const Static_Table& entry)
    : m_title(entry.title ? entry.title : ""),
      m_category(entry.category ? entry.category : "")

【讨论】:

以上是关于防止核心转储使用空指针初始化字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何防止我的程序出现此分段错误(核心转储)?

在 fscanf 之前初始化空指针

没有初始大小的字符串数组给出空指针异常

SQL查询结果中的NULL代表啥意思

为什么要使用指针,指针定义, 指针的初始化访问,空指针和坏指针,指针的算术运算

C++11 nullptr:初始化空指针