【发布时间】:2017-07-05 12:41:49
【问题描述】:
我正在寻找更详细的答案,而不是 UB 是 UB。
我有一段遗留代码,我知道它是异常的罪魁祸首。我们之前 memset 一个向量,一旦将其更改为 unordered_map,它就会在销毁时抛出异常。源代码中的什么使 memsetting 向量与 unordered_map 不同?它们都与连续内存交互...
在我们的代码中我们有这个。 (我为伪代码道歉,但重点应该还是可以理解的……)
class B
{
std::vector<CustomObject> vect;
};
struct STRUCT_A
{
B b;
};
稍后我们会这样做......
STRUCT_A m_struct_a;
memset(&m_struct_a, 0, sizeof(STRUCT_A));
即使我们 memset 一个 stl::container 也能正常工作!但是,如果我们将 B 类更改为具有映射,则析构函数会发生异常。
class B
{
std::map<CustomObject> vect;
};
所以我认为这与向量是连续的有关,所以我将其更改为 unordered_map
class B
{
std::unordered_map<CustomObject> vect;
};
析构函数仍然抛出异常。我认为这很有趣,并且认为这是一个很好的问题......
【问题讨论】:
-
你知道原因。这是未定义的行为。因此,使用矢量它恰好“工作”,但由于您的代码格式错误,它仍然无法工作。
-
"即使我们
memset一个 STL 容器,它也能正常工作" - 不。 -
memset除了 POD 之外的任何东西都只是一种创造性的方式来扩展你的程序 -
是的,我理解 memsetting 一个对象会导致未定义的行为 那么.. 问题是什么?未定义的行为是未定义的。使用不同的编译器时,您可能会观察到不同的结果。标准不保证它会以一种特定的方式工作。
-
“是的,我明白 [this] 会导致未定义的行为”和“为什么它适用于向量而不适用于其他容器”并没有一起出现。 UB 就是 UB。