与memset的初始化结构

问题描述:

我见过的代码,其中这种类型的数据结构:与memset的初始化结构

TestStruct t; 
memset(&t, 0, sizeof(TestStruct)); 

我的一些知识和其他:

struct TestStruct 
{ 
    int a; 
    std::string b; 
}; 

尽管它包含了它std:string,被作为初始化我已经阅读的帖子,上面的初始化应该是 已经导致程序崩溃(由于struct TestStruct包含std :: string这个事实),但应用程序似乎没有崩溃,为什么? 谢谢。

+1

它没有*会导致崩溃。它是*未定义的行为*。你仍然需要修复它。 – juanchopanza

+1

你真幸运。 –

+3

@MarkGarcia我会说不吉利。 – juanchopanza

你用这个调用UB,碰撞只是UB的许多化身之一。它可能稍后会在一些(可能不相关的)点崩溃,或者根本看不出来,似乎有效。

你的情况可能发生的情况是std::string在内部只是一个指向实际字符串分配的指针,无论如何已经是nullptr。但那只是一个猜测,取决于你的实现,可能是月相,不能被依赖。

初始化它自身不会造成crasches,但使用这样的对象是危险的

+0

;在结构里面?如果我只有基本类型,那么它会好吗? –

+0

已经是memset调用UB并且很危险。 – PlasmaHH

+2

@ pseudonym_127“如果我只有基本类型,那么它会好吗?”使用的术语是POD(“简单的旧数据”),是的,在这种情况下它会没事的。 – hvd

它在我的64位的Ubuntu崩溃时调用字符串的析构函数:

Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff7b78bca in ??() from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 
(gdb) bt 
#0 0x00007ffff7b78bca in ??() from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 
#1 0x00007ffff7b78c13 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()() from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 
#2 0x0000000000400808 in TestStruct::~TestStruct()() 
#3 0x0000000000400770 in main() 

,因为你改变一个物体的碰撞可能发生内部状态。初始化是这样,而不是:

TestStruct t = { }; 
你的手指

更方便,也能在C

+0

这是否显式初始化所有成员为0 /空默认值,或者你需要一个结构构造函数来发生? –

+0

http://en.cppreference.com/w/cpp/language/aggregate_initialization – user1095108

+0

该链接仅用于显式值说明,上面的语法有空括号,意味着默认的初始化。 –

memset将在std::string对象中设置的所有数据为零,这将几乎可以肯定,给你未定义行为其中,当然也包括崩溃。我使用的stl(StlPort)有一个花哨的字符串类,它在堆栈上分配短字符串,在堆上分配更长的字符串。这可能不会立即崩溃在零memset,但是,真的,没有意义的猜测,因为行为肯定不是可移植的。

你会更好写一个默认的构造函数为struct

TestStruct() : a(0){} 

其中明确0作为int内存,并且依赖于该字符串的默认构造函数。

(请记住,除默认访问外,类和结构是等效的。)