1

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

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

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

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

根据我的知识和我读过的其他帖子,上面的初始化应该导致程序崩溃(由于 struct TestStruct 包含 std::string 的事实),但应用程序似乎没有崩溃,有什么想法吗?谢谢。

4

5 回答 5

3

你用它来调用 UB,崩溃只是 UB 的众多化身之一。它可能会在稍后的某个(可能不相关的)点崩溃,或者根本不崩溃,似乎工作。

在您的情况下可能发生的情况是,这std::string在内部只是一个指向一些真正的字符串分配的指针,nullptr无论如何,这已经是。但这只是一个猜测,取决于您的实施,可能是月相,并且不能依赖。

于 2013-06-05T08:12:14.757 回答
3

崩溃可能会发生,因为您更改了对象的内部状态。像这样初始化:

TestStruct t = { };

手指更轻松,也适用于C.

于 2013-06-05T08:15:06.720 回答
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 ()
于 2013-06-05T08:15:02.707 回答
0

自己初始化可能不会导致崩溃,但使用这样的对象是危险的

于 2013-06-05T08:13:03.493 回答
0

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

您最好为以下内容编写默认构造函数struct

TestStruct() : a(0){}

它显式地将内存归零int并依赖于字符串的默认构造函数。

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

于 2013-06-05T08:17:54.250 回答