c++ - 在全局容器中存储局部变量的内存地址
问题描述
在我的理解中,不可能将局部内存的地址存储在全局容器中,因为局部变量最终会被销毁。
class AA {
std::string name;
public:
explicit AA(std::string n) : name(n) {}
std::string getName() const {
return name;
}
};
class Y {
std::vector<std::reference_wrapper<AA>> x;
public:
void addAA(AA& aa) {
x.emplace_back(aa);
}
AA& getLastA() {
return x.back();
}
};
void foobar(Y& y) {
AA aa("aa");
y.addAA(aa);
}
int main() {
Y y;
foobar(y);
std::cout << y.getLastA().getName() << std::endl; // error - probably because the local aa has been destroyed.
return 0;
}
但是,我不明白为什么这段代码有效:
void foobar(Y& y, AA& aa) {
y.addAA(aa);
}
int main() {
Y y;
{
AA aa("aa");
foobar(y,aa);
}
std::cout << y.getLastA().getName() << std::endl;
return 0;
}
aa
再次在另一个范围内创建,应该被销毁。但是,它可以在稍后获得它的名字main
。代码工作正常。
为什么我们不会在第二种情况下得到错误?
解决方案
Rust 有一个渗透到语言中的借用检查器,这是它的定义特征。在 Rust 中,这样的代码是被禁止的。
C++ 是一门历史悠久的语言,我认为没有错误诊断的原因是因为在创建该语言时它不是问题。在那个时候,C 哲学是主流:“程序员无所不知”。因此,程序员知道他们违反了生命周期安全,因此错误消息是多余的。
现在,C++ 委员会全神贯注于确保 C++ 的版本尽可能向后兼容,并且强制提供的代码段失败可能会破坏现有代码。因此,不会在不久的将来将终生违规行为纳入标准。
对于此类问题,委员会似乎倾向于认为,如果您想强制执行标准未涵盖的内容,则应使用第三方静态分析工具。但是,其中很少,最值得注意的是clang-tidy
,但据我所知,它们都不支持严格的生命周期分析来检测您的代码段所展示的错误。
推荐阅读
- python - 为什么numpy数组中相同索引选择的输出存在差异
- mysql - How to copy column values to a new SQL table, remove duplicates and create mappings?
- java - Why does java.util.Optional.ofNullable() expect @NonNullable?
- julia - 为值分配颜色
- sql - Try to make a view but have a problem ORA-00979: not a GROUP BY expression
- java - Flutter doctor --android-licenses problem
- python - xpath for scraping critic's reviews from rotten tomatoes
- python - how to verify a coupon using django framework and sqlite?
- flutter - Flutter load list with id
- pandas - My bokeh could runs fine, but outputs a blank chart. What am I doing wrong?