防止核心转储使用空指针初始化字符串
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
有一个引用成员,该引用成员通过传递给构造函数的指针的间接结果被初始化(没有Ulrich 提到的不必要的nullptr
检查)?然后它的存储可以被优化掉,虽然我不知道std::string
的其他数据成员。
【参考方案1】:
对于您的第一个问题,您可以使用三元运算符来检查空指针:
Ingredient(const Static_Table& entry)
: m_title(entry.title ? entry.title : ""),
m_category(entry.category ? entry.category : "")
【讨论】:
以上是关于防止核心转储使用空指针初始化字符串的主要内容,如果未能解决你的问题,请参考以下文章