使用memset初始化struct

时间:2013-06-05 08:09:41

标签: c++

我见过这种类型的数据结构的代码:

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

虽然其中包含std:string,但初始化为:

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

对我的一些知识和其他帖子我已经阅读过,上面的初始化应该 导致程序崩溃(由于struct TestStruct包含std :: string的事实),但应用程序似乎没有崩溃,任何想法为什么? 感谢。

5 个答案:

答案 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的内存归零并依赖于字符串的默认构造函数。

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