C++ 为什么以这种方式访问联合中的指针会导致分段错误?

C++ 为什么以这种方式访问联合中的指针会导致分段错误?,c++,g++-5,C++,G++ 5,为什么以下代码会导致分段错误 #include <string> union U { bool boolean; double number; std::string* str_ptr; }; int main() { U u{new std::string("A")}; delete u.str_ptr; return 0; // return u.str_ptr->compare("A"); } #包括 联合大学

为什么以下代码会导致分段错误

#include <string>

union U {
    bool boolean;
    double number;
    std::string* str_ptr;
};

int main()
{
    U u{new std::string("A")};
    delete u.str_ptr;
    return 0;
    // return u.str_ptr->compare("A");
}
#包括
联合大学{
布尔布尔;
双数;
std::string*str_ptr;
};
int main()
{
U{newstd::string(“A”)};
删除u.str_ptr;
返回0;
//返回u.str_ptr->compare(“A”);
}
我应该说,如果我不使用return语句,而是尝试以其他方式访问指针,这似乎并不重要。例如,替换
删除u.str\u ptr;返回0
返回u.str_ptr->比较(“A”)我仍然有一个分段错误


如果这是特定于编译器的,我使用的是
g++(Ubuntu 5.4.0-6ubuntu1~16.04.2)5.4.0 20160609

除非是联合体,否则访问
u.str\u ptr
是不合法的。但是联合中的最后一个成员集是
布尔值
,因为具有一个未指定值的初始值设定项列表将设置第一个成员

请参阅。

U{new std::string(“A”)}下的“成员生存期”
不符合您的想法,正如您所说的,它使用调用
new
的值初始化第一个成员。如果要设置正确的成员,请使用以下命令:

U u{.str_ptr=new std::string("A")};
---编辑---

这是
gcc
扩展,标准规定,当使用大括号内的初始值设定项初始化联合时,大括号只能包含联合的第一个非静态数据成员的初始值设定项子句。。然后使用standard,您只能执行以下操作:

U u;
u.str_ptr = new std::string("A");

new返回的指针正在隐式转换为第一个成员的类型,即type
bool
。由于C++允许转换,所以不会发生错误。
// effectively what is happening.
U u{ new std::string("A") != 0 };

当使用这样的联合时,最好是显式地直接分配给成员。但是如果你真的想这样做,就让
str_ptr
成为第一个成员。

这是编译吗?它看起来像C99指定的初始化器,不是C++的一部分。您引用了错误语言的引用。幸运的是,在编写时,(C++)中的相同(模数指定的初始化器)在C++中是正确的。这在那页上是不存在的。。。