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
下面是我的代码和执行结果。
#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