Below is my code and the execution result.
#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)
....
In my opinion, the combination of reference and emplace_back is wrong.
But why? What happened?
CodePudding user response:
because after emplace new element to blocks, may element's address have change (internal vector expanding operation )-> you save previous address is incorrect. to fix it you just change order of commands.
std::vector<Block> blocks;
blocks.emplace_back(1);
blocks.emplace_back(2);
Block &block = blocks[0];
std::max(1, block.value 1);
show diffence address after each 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);
result:
&blocks[0]0xae1eb0
destructor ,value 1
&blocks[0]0xae2ee0
destructor ,value 1
destructor ,value 1
destructor ,value 2