【问题标题】:"AddressSanitizer: stack-use-after-scope" when trying to access element of vector of pointers尝试访问指针向量的元素时出现“AddressSanitizer:stack-use-after-scope”
【发布时间】:2021-12-30 10:05:43
【问题描述】:

为什么是下面的代码

#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] = &num;
    }

    std::cout << nums[1]->number << "\n";

    return 0;
}

触发“AddressSanitizer: stack-use-after-scope”,但是当我评论第 15 行时:std::cout &lt;&lt; nums[5]-&gt;number &lt;&lt; "\n"; 它编译得好吗?如何解决?

编译命令:clang++ main.cpp -fsanitize=address,undefined -fno-sanitize-recover=all -std=c++17 -O2 -Wall -Werror -Wsign-compare -g -o debug_solution &amp;&amp; ./debug_solution

【问题讨论】:

  • 阅读您的 C++ 教科书并了解 new 运算符。还有关于std::shared_ptr,当你在它的时候。
  • 你正在将num的地址保存到向量中:num的生命周期是多少?
  • 不相关:在 C++ 中,您将结构定义为 struct Number { ... };
  • 注意:如果您打印出存储在nums 中的地址,则很有可能您会发现它们都是相同的。应该给你一些关于这里出了什么问题的提示。
  • 谢谢大家!我正在成为 C++ 领主的路上。

标签: c++ address-sanitizer


【解决方案1】:

问题是您正在存储一个指向堆栈上的值的指针,该值超出范围并被销毁,留下一个悬空指针。

std::vector<Number*> nums(5);
for (size_t i = 0; i < nums.size(); ++i) {
    Number num;
    nums[i] = &num;
    // 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&lt;Number&gt;

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&lt;std::unique_ptr&lt;Number&gt;&gt;std::vector&lt;std::shared_ptr&lt;Number&gt;&gt;,具体取决于对象是否需要在多个组件之间共享。

【讨论】:

  • 在没有指针的情况下,根本不需要循环。 std::vector&lt;Number&gt; nums(5); 创建了所有必需的默认构造 Numbers。
  • 非常真实,添加了注释。
  • 非常感谢!这真的只是一个玩具示例,具有相同问题的真实代码大约是 300 行(完美的哈希实现)。
猜你喜欢
  • 2018-12-16
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-27
  • 1970-01-01
相关资源
最近更新 更多