Why the following code
#include <iostream>
#include <vector>
typedef struct Number {
int number = 15;
} Number;
int main() {
std::vector<Number*> nums(5);
for (size_t i = 0; i < nums.size(); i) {
Number num;
nums[i] = #
}
std::cout << nums[1]->number << "\n";
return 0;
}
trigger "AddressSanitizer: stack-use-after-scope", but when i comment line 15: std::cout << nums[5]->number << "\n";
it compiles well? How to fix it?
Compile command: clang main.cpp -fsanitize=address,undefined -fno-sanitize-recover=all -std=c 17 -O2 -Wall -Werror -Wsign-compare -g -o debug_solution && ./debug_solution
CodePudding user response:
The issue is that you are storing a pointer to a value on the stack that goes out of scope and gets destroyed, leaving a dangling pointer.
std::vector<Number*> nums(5);
for (size_t i = 0; i < nums.size(); i) {
Number num;
nums[i] = #
// num goes out of scope here and num[i] has a dangling pointer
// to an invalid object
}
std::cout << nums[1]->number << "\n";
In this toy example, I see no reason to use pointers at all, and the fix would be just to use a std::vector<Number>
:
std::vector<Number> nums(5);
// per comment by @user4581301
// this loop is not really needed, as the constuctor will
// default-construct the elements for you
for (size_t i = 0; i < nums.size(); i) {
Number num;
nums[i] = num;
}
std::cout << nums[1].number << "\n";
If you really do need dynamic memory allocation on the heap, you should look at using an std::vector<std::unique_ptr<Number>>
or std::vector<std::shared_ptr<Number>>
depending on if the object needs to be shared between multiple components.