C++ 使用std::vector<&燃气轮机;和std::shared_ptr<&燃气轮机;应该引起错误
以下是我所做工作的代码:C++ 使用std::vector<&燃气轮机;和std::shared_ptr<&燃气轮机;应该引起错误,c++,c++11,g++,c++14,C++,C++11,G++,C++14,以下是我所做工作的代码: #include <iostream> #include <vector> #include <memory> using namespace std; int main() { vector<int> ar = {1}; shared_ptr<int> sp(&ar[0]); cout<<*sp<<endl; // ---- [1] ar[0] = 10
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
int main()
{
vector<int> ar = {1};
shared_ptr<int> sp(&ar[0]);
cout<<*sp<<endl; // ---- [1]
ar[0] = 10;
cout<<*sp<<endl; // ---- [2]
ar.clear();
cout<<*sp<<endl; // ---- [3]
return 0;
}
我认为应该在运行时出现任何错误,而不是在[3]
处执行cout
,因为要访问的对象已被删除。如何在[3]
中打印10
?或者我应该使用任何g++
标志,我只是在使用g++-std=c++14a1.cpp&&a.out
编辑:在上运行时,我发现clang++
正在
`*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x0000000002138010 ***`
但是
g++
不是。这是一种未定义的行为。它可能会也可能不会打印10
std::vector::clear()
删除了对象,不保证重新分配。所以系统可能不会重用那个内存,所以若你们访问相同的内存位置,你们可能会得到旧的值
有一个有趣的观察结果,如果您在std::vector::clear()
操作之后检查std::shared\u ptr::use\u cout()
,您可以看到答案1
vector<int> ar = {1};
shared_ptr<int> sp(&ar[0]);
cout<<*sp<<"\n"; // ---- [1]
ar[0] = 10;
cout<<*sp<<"\n"; // ---- [2]
ar.clear();
cout<< sp.use_count()<<"\n";
cout<<*sp<<endl; // ---- [3]
这是一种未定义的行为。它可能会也可能不会打印10
std::vector::clear()
删除了对象,不保证重新分配。所以系统可能不会重用那个内存,所以若你们访问相同的内存位置,你们可能会得到旧的值
有一个有趣的观察结果,如果您在std::vector::clear()
操作之后检查std::shared\u ptr::use\u cout()
,您可以看到答案1
vector<int> ar = {1};
shared_ptr<int> sp(&ar[0]);
cout<<*sp<<"\n"; // ---- [1]
ar[0] = 10;
cout<<*sp<<"\n"; // ---- [2]
ar.clear();
cout<< sp.use_count()<<"\n";
cout<<*sp<<endl; // ---- [3]
您的代码中有几处错误。最明显的一点是,您正在创建一个
shared_ptr
来管理一个已经由vector
管理的对象,并且很可能在main
的末尾得到双重删除
另一个问题是,您有一个指向对象的指针,并在对象被删除后使用它,因为
std::vector::clear
不会释放您正在访问的内存,该内存仍然由该向量管理,这就是为什么它不会爆炸,但该对象不再存在,您不应该访问它。如果不是一个int
而是一个std::string
程序可能已经崩溃(它也可能没有崩溃,这是未定义行为的本质)您的代码中有一些错误。最明显的一点是,您正在创建一个shared_ptr
来管理一个已经由vector
管理的对象,并且很可能在main
的末尾得到双重删除
另一个问题是,您有一个指向对象的指针,并在对象被删除后使用它,因为
std::vector::clear
不会释放您正在访问的内存,该内存仍然由该向量管理,这就是为什么它不会爆炸,但该对象不再存在,您不应该访问它。如果不是一个int
而是一个std::string
程序可能已经崩溃(它也可能没有崩溃,这是未定义行为的本质)当您试图访问向量的当前边界之外时,您几乎忽略了任何可能会导致运行时错误的东西
如果你想检查边界,你可以考虑这样的事情:< /P>
std::vector<int> ar { 1 };
std::cout << ar.at(0); // no problem
ar.clear();
std::cout << ar.at(0); // guaranteed to throw an exception
std::向量ar{1};
std::cout当您试图访问向量的当前边界之外的内容时,您几乎忽略了任何可能导致运行时错误的内容
如果你想检查边界,你可以考虑这样的事情:< /P>
std::vector<int> ar { 1 };
std::cout << ar.at(0); // no problem
ar.clear();
std::cout << ar.at(0); // guaranteed to throw an exception
std::向量ar{1};
std::当它到达main
的末尾时,难道它没有崩溃吗?@DavidRodriguez dribea甚至没有崩溃,只是像什么都没发生一样退出!清除一个向量并不一定意味着它分配的内存被删除。这是未定义的行为,未定义的行为是未定义的。它可能会崩溃,也可能不会。所有你正在做的是访问内存,你不应该做,它不应该做,但它不一定致命。人们有何想法,写坏C++代码意味着你保证崩溃了吗?它不是崩溃时,它达到了结束代码>主< /代码>?@ DavidRodriguez驱动器没有甚至崩溃,就像什么都没发生一样离开!清除一个向量并不一定意味着它分配的内存被删除。这是未定义的行为,未定义的行为是未定义的。它可能会崩溃,也可能不会。所有你正在做的是访问内存,你不应该,它不应该做,但它不一定致命。人们认为,写坏的C++代码意味着你保证崩溃了吗?<代码> STD::vector::()(代码)>不释放,它仍然是由向量管理的内存。尽管如此,它仍然是未定义的行为,因为对象不再存在。std::vector::clear()
不会取消分配,它仍然是由vector管理的内存。但是,它仍然是未定义的行为,因为对象不再存在。是的,我的程序崩溃了std::string
)是的,我的程序崩溃了std::string
)