"AddressSanitizer: stack-use-after-scope" 尝试访问指针向量的元素时
"AddressSanitizer: stack-use-after-scope" when trying to access element of vector of pointers
为什么是下面的代码
#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;
}
触发“AddressSanitizer: stack-use-after-scope”,但是当我评论第 15 行时:std::cout << nums[5]->number << "\n";
它编译得好吗?如何解决?
编译命令:clang++ main.cpp -fsanitize=address,undefined -fno-sanitize-recover=all -std=c++17 -O2 -Wall -Werror -Wsign-compare -g -o debug_solution && ./debug_solution
问题是您在堆栈上存储了一个指向值的指针,该值超出范围并被销毁,留下悬空指针。
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";
在这个玩具示例中,我认为根本没有理由使用指针,解决方法就是使用 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";
如果您确实需要在堆上动态分配内存,您应该考虑使用 std::vector<std::unique_ptr<Number>>
或 std::vector<std::shared_ptr<Number>>
,具体取决于对象是否需要在多个组件之间共享。
为什么是下面的代码
#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;
}
触发“AddressSanitizer: stack-use-after-scope”,但是当我评论第 15 行时:std::cout << nums[5]->number << "\n";
它编译得好吗?如何解决?
编译命令:clang++ main.cpp -fsanitize=address,undefined -fno-sanitize-recover=all -std=c++17 -O2 -Wall -Werror -Wsign-compare -g -o debug_solution && ./debug_solution
问题是您在堆栈上存储了一个指向值的指针,该值超出范围并被销毁,留下悬空指针。
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";
在这个玩具示例中,我认为根本没有理由使用指针,解决方法就是使用 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";
如果您确实需要在堆上动态分配内存,您应该考虑使用 std::vector<std::unique_ptr<Number>>
或 std::vector<std::shared_ptr<Number>>
,具体取决于对象是否需要在多个组件之间共享。