C++ 从字符串和向量中移动是否需要不拥有任何堆内存?
我知道从对象中移动的对象处于未指定但可破坏的状态,我通常知道这意味着它们可以拥有内存、文件句柄。。。 但我不知道是否允许从C++ 从字符串和向量中移动是否需要不拥有任何堆内存?,c++,move-semantics,C++,Move Semantics,我知道从对象中移动的对象处于未指定但可破坏的状态,我通常知道这意味着它们可以拥有内存、文件句柄。。。 但我不知道是否允许从std::strings和std::vectors中移动来拥有任何内存 例如,下面的函数可能会泄漏内存,还是按照C++标准? void f(){ std::aligned_storage_t<sizeof(std::string), alignof(std::string)> memory; std::string& src = *new
std::string
s和std::vector
s中移动来拥有任何内存
例如,下面的函数可能会泄漏内存,还是按照C++标准?
void f(){
std::aligned_storage_t<sizeof(std::string), alignof(std::string)> memory;
std::string& src = *new (&memory) std::string ("98->03->11->14->17->20");
std::string dest(std::move(src ));
}
void f(){
std::对齐的存储存储器;
std::string&src=*新建(&memory)std::string(“98->03->11->14->17->20”);
std::stringdest(std::move(src));
}
注:
- 我对ISO标准感兴趣,我知道这是最明显的
实现
在src
移动后不应拥有任何内存,I 我对本规范的“法律”地位感兴趣
我知道这里提出的代码不是C++中的“正确”方式,而是
只是一个例子来解释我的问题
- 我问的是关于std::string和std::vector的问题,我知道这不是一般的问题
如果这些都是不合理的可能性;但是跳过销毁也是如此。标准中没有要求从对象移动到不再拥有任何资源的内容。(除了性能保证,但我不认为它们阻止了这种情况下的所有权) 关于您的计划,请参见[basic.life/4]: 对于具有非平凡析构函数的类类型的对象,在重用或释放该对象占用的存储之前,程序不需要显式调用析构函数;但是,如果没有显式调用析构函数,或者如果没有使用删除表达式(5.3.5)来释放存储,则不应隐式调用析构函数,并且依赖于析构函数产生的副作用的任何程序都具有未定义的行为 “任何依赖于副作用的程序”这一部分并不像我们在标准文件中看到的那样精确,但它通常被解释为“除了没有可观察行为的析构函数之外的任何东西”。我们不知道库实现可能在向量和字符串的析构函数中放入了什么(例如,它可能在调试模式下具有调试跟踪)
因此,我想说,您的程序由于忽略析构函数调用而导致未定义的行为,尽管还有一些争议。如果moved from
std::string
“拥有”任何内存,那么当moved from对象被销毁时,它将被释放。每一个被建造的物体都必须被摧毁。“从对象移动”也不例外。“从中移动”对象是否实际拥有任何内存(在其自身销毁时需要释放)尚未确定。显示的代码是未定义的行为,因为对齐存储中的std::string
对象从未被销毁。要简单地修复它,请显式调用其析构函数。现在它是被定义的行为(除非抛出的异常在不销毁对象的情况下离开此范围。我们所知道的只是它处于有效但未指定的状态。尽管我很努力,我无法想象为什么人们有理由不直接调用析构函数,按照通常的布局构造/销毁规范,而不管是否已执行移动。我明白了关于std::vector
或std::basic_string
,没有可想象的标准支持例外。这类似于询问构造空vector
或string
而不销毁它是否会泄漏。“拥有内存”与标准中使用或描述的任何术语都不对应。(有拥有和不拥有的智能指针和std::function
对象,但“不拥有”的含义也并不意味着你在这里要问什么。)想到一件事——实现“小字符串优化”(SSO)的STL库对于std::string
。当启用SSO的字符串包含小内容时,字符数据不会存储在动态内存中,因此无法移动到另一个字符串对象。只能将内容从一个缓冲区复制到另一个缓冲区。从中移动的字符串保留其内存缓冲区的所有权,尽管其大小
重置为0 d"动"起来。对于非SSO字符串,以及内容长于SSO缓冲区的字符串,内存是动态分配的,因此可以在字符串对象之间转移所有权。恒定时间复杂性保证禁止无条件复制所有字符串进行移动构造。@user23当然可以,但它可以复制长度不超过527432的所有字符串。任何基于堆的复制品已经是病态的了;那么为什么仅仅停留在精神错乱上呢?但这一点很好;编辑在。