如果对象调整自己的容器大小会怎样?

use*_*100 8 c++ memory-management stl

这不是一个关于你为什么要编写这样的代码的问题,而是一个关于方法如何与它所绑定的对象相关的问题.

如果我有一个像这样的结构:

struct F
{
    // some member variables
    void doSomething(std::vector<F>& vec)
    {
        // do some stuff
        vec.push_back(F());
        // do some more stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

我这样使用它:

std::vector<F>(10) vec;
vec[0].doSomething(vec);
Run Code Online (Sandbox Code Playgroud)

如果push_back(...)in doSomething(...)导致向量扩展会发生什么?这意味着vec[0]将在执行其方法的过程中复制然后删除.这不好.

有人可以解释这里到底发生了什么?

  • 程序会立即崩溃吗?该方法是否只是尝试对不存在的数据进行操作?
  • 该方法是否会对其对象进行"孤立"操作,直到遇到更改对象状态等问题为止?

我对方法调用如何与关联对象相关感兴趣.

And*_*oss 7

是的,这很糟糕.当你在doSomething()中时,你的对象可能被复制(或者在C++ 11中被移动,如果区别与你的代码相关).因此,在push_back()返回后,this指针可能不再指向对象的位置.对于vector :: push_back()的特定情况,可能已释放此指向的内存,并将数据复制到其他位置的新数组中.对于将其元素留在原位的其他容器(例如列表),这(可能)根本不会导致问题.

实际上,您的代码不太可能立即崩溃.最可能的情况是写入空闲内存和F对象状态的静默损坏.您可以使用valgrind之类的工具来检测此类行为.

但基本上你有正确的想法:不要这样做,这是不安全的.

  • 您几乎可以在不崩溃的情况下始终写入"释放"的内存.这就是内存映射的工作方式.地图保留在原地以供将来的对象使用.但是,你可以**永远不会"无问题地"写入释放的内存.只是"问题"是崩溃之外的事情. (2认同)