我见过这种类型的数据结构的代码:
struct TestStruct
{
int a;
std::string b;
};
虽然其中包含std:string
,但初始化为:
TestStruct t;
memset(&t, 0, sizeof(TestStruct));
对我的一些知识和其他帖子我已经阅读过,上面的初始化应该 导致程序崩溃(由于struct TestStruct包含std :: string的事实),但应用程序似乎没有崩溃,任何想法为什么? 感谢。
答案 0 :(得分:3)
你用它调用UB,崩溃只是UB的许多化身之一。它可能会在某些(可能是无关的)点崩溃,或者根本不会崩溃,似乎有效。
在你的情况下可能发生的事情是std::string
内部只是指向一些真实字符串分配的指针,反正已经nullptr
。但这只是一个猜测,取决于你的实施,可能是月相,并不是可靠的。
答案 1 :(得分:3)
可能会发生崩溃,因为您更改了对象的内部状态。像这样初始化:
TestStruct t = { };
您的手指更容易,也适用于C
。
答案 2 :(得分:1)
在调用字符串析构函数时,它会在我的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 ()
答案 3 :(得分:0)
初始化本身可能不会导致崩溃,但使用此类对象是危险的
答案 4 :(得分:0)
memset
会将std::string
对象中的所有数据设置为零,这几乎肯定会为您提供未定义的行为,当然,这可能包括< em>不崩溃。我使用的stl(StlPort)有一个花哨的字符串类,它在堆栈上分配短字符串,在堆上分配更长的字符串。这可能不会立即在零memset
上崩溃,但实际上,没有必要推测这种行为当然不可移植。
最好为struct
编写默认构造函数:
TestStruct() : a(0){}
明确地将int
的内存归零并依赖于字符串的默认构造函数。
(请记住,除了默认访问权限之外,类和结构是等效的。)