Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unique_ptr:在列表中放置时未分配要释放的指针 我有一个简单的C++程序,比如:: #include <iostream> #include <list> #include <memory> int main(void) { std::list<std::unique_ptr<int>> l; int x = 5; // throws runtime error: pointer being freed was not allocated l.emplace_back(&x); }_C++_C++11_Unique Ptr - Fatal编程技术网

Unique_ptr:在列表中放置时未分配要释放的指针 我有一个简单的C++程序,比如:: #include <iostream> #include <list> #include <memory> int main(void) { std::list<std::unique_ptr<int>> l; int x = 5; // throws runtime error: pointer being freed was not allocated l.emplace_back(&x); }

Unique_ptr:在列表中放置时未分配要释放的指针 我有一个简单的C++程序,比如:: #include <iostream> #include <list> #include <memory> int main(void) { std::list<std::unique_ptr<int>> l; int x = 5; // throws runtime error: pointer being freed was not allocated l.emplace_back(&x); },c++,c++11,unique-ptr,C++,C++11,Unique Ptr,但是,当上述唯一\u ptr p超出范围并被销毁时,程序运行正常。为什么第一个程序在销毁唯一\u ptr时给我一个错误,而第二个程序没有?为什么在列表中放置unique_ptr会导致其销毁失败 我认为发生的情况是,第二个示例中的变量p刚刚得到优化,因此没有导致运行时错误 但是发生的错误很明显,它试图释放堆栈上分配的内存。请注意,智能指针通常与堆分配的内存一起使用,而不是在堆栈上分配的内存。我复制了您的代码并编译了它: $ g++ omg.cpp && ./a.exe Aborte

但是,当上述
唯一\u ptr p
超出范围并被销毁时,程序运行正常。为什么第一个程序在销毁
唯一\u ptr
时给我一个错误,而第二个程序没有?为什么在列表中放置
unique_ptr
会导致其销毁失败

我认为发生的情况是,第二个示例中的变量
p
刚刚得到优化,因此没有导致运行时错误


但是发生的错误很明显,它试图释放堆栈上分配的内存。请注意,智能指针通常与堆分配的内存一起使用,而不是在堆栈上分配的内存。

我复制了您的代码并编译了它:

$ g++ omg.cpp && ./a.exe
Aborted (core dumped)
您可以尝试添加另一个间接级别:

int main(void) {
    int x = 5;
    {
        std::unique_ptr<int> p(&x);
    }
}
int main(无效){
int x=5;
{
std::唯一的ptr p&x;
}
}

看看它是否有帮助。

未定义的行为可能导致任何事情,从崩溃到显然成功的运行,到英国投票退出欧盟(哎呀,对不起,伙计们……空指针取消引用能做什么真是太神奇了)

编译器是极其复杂的东西。您的程序不是将由目标计算机按顺序执行的指令的一对一映射;它大致描述了您希望计算机的行为方式。两者之间的转换非常深奥和复杂。当你离开piste时,你破坏了语言,使编译器的内部工作——不断地做出假设,走捷径,它知道这是允许的,特别是在应用所谓的“优化”时——以不可预测的方式被破坏

这是其中之一

简言之,如果你希望UB做一些特别的事情,那么你已经失败了

通过分析编译器的源代码和生成的程序集,可以准确地确定UB在本例中的行为。但这将是一个漫长、艰巨且最终毫无意义的过程


只是不要把你没有动态分配的东西变成智能指针(或者,如果你真的想出于某种原因,提供一个自定义的删除程序,它不会试图删除那些不是新的东西)。简单

您可能可以使用no-op-deleter使其正确地处理堆栈分配的对象……只是出于好奇。您是对的。使用-O0运行会产生错误。但是,使用
volatile std::unique_ptr p(&x)运行仍然不会产生错误,尽管我认为volatile限定符会阻止优化。@RaeesRajwani制作
p
volatile
在这里没有什么有趣的地方。@RaeesRajwani这是对
volatile
所做的大量过度简化,可能是你的整个程序都被优化了,因为它什么都不做。(在列表的情况下,编译器很难证明这一点,所以可能不麻烦。)@RaeesRajwani确实如此,但它仍然没有改变代码不必崩溃的事实。未定义的行为意味着不需要发生错误。当然,它和我的5.3一样……运行二进制文件时会发生什么?我没有运行,因为只允许编译代码,而不允许运行它。但即使我运行了它,它也会抛出同样的错误,因为释放堆栈上分配的内存只是一个“不”字。这不是一个间接级别。@ProXicT no,您不能依赖此处的错误/诊断(如问题所示)。@LightnessRacesinOrbit是的,您是对的。我的意思是释放堆栈内存可以产生任何结果。两者都是UB,因此行为可能不同。
int main(void) {
    int x = 5;
    {
        std::unique_ptr<int> p(&x);
    }
}