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