#include <iostream>
#include <vector>
#include <cstring>
using namespace std; //please ignore bad practices like this and everything being set to public. Its just for sake of demonstration.
vector<int>& f() {
vector<int> a = *new vector<int>{15, 15, 16};
return a;
}
int main () {
vector<int>& b = f();
for (auto x: b) {
cout << x << endl;
}
cout << "finished" << endl;
}
Hi:
In the code above, I’m using dynamic allocated memory so that vector a would have its memory stored on the heap, so it can avoid getting deleted after the function exits. But for some reason it didn’t. The code gives me this error that can’t be understood:
=================================================================
==22==ERROR: AddressSanitizer: heap-use-after-free on address 0x602000000030 at pc 0x000000354a2c bp 0x7ffc1174eb30 sp 0x7ffc1174eb28
READ of size 4 at 0x602000000030 thread T0
#1 0x7f2c73349082 (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
0x602000000030 is located 0 bytes inside of 12-byte region [0x602000000030,0x60200000003c)
freed by thread T0 here:
#3 0x7f2c73349082 (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
previously allocated by thread T0 here:
#5 0x7f2c73349082 (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
Shadow bytes around the buggy address:
0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa 00 04 fa fa[fd]fd fa fa fa fa fa fa fa fa
0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==22==ABORTING
I feel like I’m missing something — I’ll rename/reword my question more appropriately afterwards.
>Solution :
vector<int>& f() {
vector<int> a = *new vector<int>{15, 15, 16};
return a;
}
This is calling the copy constructor of a and passing the heap allocated object to it. a is not created on the heap. It is destroyed when f() exits, leaving the returned reference dangling.
Use a reference instead of a second object. Just bind the already created vector on the heap to the reference that gets returned.
vector<int>& f() {
vector<int>& a = *new vector<int>{15, 15, 16};
return a;
}
While this may work, This is bad design
The proper way to make this code work is to simply return the vector from your function and let the compiler move it:
vector<int> f() {
vector<int> a{15, 15, 16};
return a;
}
...
vector<int> b = f();