访问不存在的对象是否属于C++未定义行为?标准条款适用疑问
访问不存在的对象是否属于C++未定义行为?
代码示例
void* p = operator new(sizeof(std::string)); *static_cast<std::string*>(p) = "string";
问题分析
这段代码确实属于未定义行为,你忽略的核心要点在于:对*static_cast<std::string*>(p)的赋值操作,本质是尝试调用std::string的赋值运算符,而该操作要求指针指向一个已存在且处于生命周期内的std::string对象,否则直接触发未定义行为。
具体结合标准条款拆解:
operator new的本质:它仅分配了足够容纳std::string的内存空间,但根据[intro.object]/10,std::string不属于隐式生命周期类型,因此这块内存中不会自动创建std::string对象——此时内存处于原始未初始化状态,不存在任何对象。- 为什么[basic.life]/6不适用:该条款针对的是「内存已分配/未释放,但对象生命周期未开始/已结束」的场景,而你的情况是完全没有对象被创建,需要参考更基础的规则:
根据[basic.lval]/11:若左值引用的对象不存在,或对象生命周期未开始/已结束,除了用于对象创建的特定场景外,使用该左值的行为属于未定义行为。
你代码中的*static_cast<std::string*>(p)是一个左值,它试图引用一个根本不存在的std::string对象,后续的赋值操作直接违反了这条规则。 - 合法的修正方式:必须先通过placement new在分配的内存中显式构造
std::string对象,之后才能进行赋值操作,示例如下:
void* p = operator new(sizeof(std::string)); // 显式构造std::string对象 new(p) std::string; *static_cast<std::string*>(p) = "string"; // 记得后续显式析构 static_cast<std::string*>(p)->~basic_string(); operator delete(p);
内容的提问来源于stack exchange,提问作者Blackteahamburger
相关产品推荐
相关产品推荐

