C++ [heap-use-after-free error] with referenceing and push_back to vector

C++ [heap-use-after-free error] with referencing and push_back to vector

下面是我的代码和执行结果。

#include<vector>
#include<algorithm>

typedef struct Block {
    int value;
    Block(int value): value(value) {}
} Block;

int main() {
    std::vector<Block> blocks;
    blocks.emplace_back(1);
    Block& block = blocks[0];
    blocks.emplace_back(2);
    std::max(1, block.value + 1);
    return 0;
}
00699 ➤ g++ -std=c++11 -fsanitize=address  question.cpp; ./a.out
=================================================================
==32403==ERROR: AddressSanitizer: heap-use-after-free on address 0x000106c00730 at pc 0x0001028fbd90 bp 0x00016d507310 sp 0x00016d507308
READ of size 4 at 0x000106c00730 thread T0
    #0 0x1028fbd8c in main+0x300 (a.out:arm64+0x100003d8c)
    #1 0x1029490f0 in start+0x204 (dyld:arm64e+0x50f0)
....

在我看来,引用和emplace_back的组合是错误的。
但为什么?发生什么事了?

因为将新元素放置到块中后,元素的地址可能会发生变化(内部矢量扩展操作)->您保存的先前地址不正确。要修复它,您只需更改命令的顺序。

std::vector<Block> blocks;
blocks.emplace_back(1);
blocks.emplace_back(2);
Block &block = blocks[0];

std::max(1, block.value + 1);

在每个 emplace_back

之后显示差异地址
std::vector<Block> blocks;
blocks.emplace_back(1);
Block block = blocks[0]; 
cout << "&blocks[0]" << & blocks[0] << "\n";
blocks.emplace_back(2);
cout << "&blocks[0]" << & blocks[0] << "\n";

std::max(1, blocks[0].value + 1);

结果:

&blocks[0]0xae1eb0
destructor ,value 1
&blocks[0]0xae2ee0
destructor ,value 1
destructor ,value 1
destructor ,value 2

https://godbolt.org/z/Y9xrv64aq