gpt4 book ai didi

c++ - string_view 真的会导致释放后使用错误吗?

转载 作者:太空狗 更新时间:2023-10-29 20:19:57 24 4
gpt4 key购买 nike

根据一篇文章(herethere),这段代码是一个错误的免费示例:

#include <iostream>
#include <string>
#include <string_view>

int main() {
std::string s = "Hellooooooooooooooo ";
std::string_view sv = s + "World\n";
std::cout << sv;
}

文章中指出 string s 将在 string_view 时被释放用来!这违背了我的调试经验。但我要求你确认/验证/检查这一点。

根据我的经验,堆栈/作用域变量在作用域的导出被释放(调用析构函数是更正确的措辞)。这意味着在这种情况下,这将发生在 std::cout << sv; 之后

不过我从来没有用过string_view ,所以我不知道这个对象的任何内部机制。

如果这确实是一种危险行为,您能解释一下吗?否则,我很高兴看到确认范围变量析构函数仅在当前范围的退出时自然地被调用,或者当异常被抛出时,中断当前范围中的线程。


编辑:经过前两个答案,真的是use-after-free usage。

附属问题:你认为我们可以在 string_view 的定义中添加一个带有 delete 关键字的移动构造函数来禁止它吗?

最佳答案

这段代码的问题...

std::string_view sv = s + "World\n";

... 是 sv 未设置为 s 而是设置为由表达式 s + "创建的无名临时世界\n"temporary 在整个表达式结束(在分号处)后立即被销毁。

所以是的,这是一个“释放后使用”类型的错误。

如果你想延长那个临时的生命,你必须将它分配给一个将维护它的变量 - 就像一个新的 std::string 对象:

std::string sv = s + "World\n"; // copy the temporary to new storage in sv

std::string_view 只是字符串的“ View ”,它本身不是字符串。它仅在它“查看”的字符串有效时才有效。

这里还有另一个怪癖。您还可以将 temporary 绑定(bind)到 const reference 以延长临时对象的生命周期:

std::string const& sv = s + "World\n"; // just keep the temporary living

为什么允许从临时初始化std::string_view

我不能代表标准委员会发言,但我怀疑 std::string_view 应该用作函数参数,以便可以将临时对象传递给函数(比如 with常量引用)。显然,生命周期适合这种情况。

如果我们禁止从临时对象进行初始化,那么 std::string_view 的主要用途将被否定。在调用使过程变得尴尬的函数之前,您将被迫创建一个新的 std::string(或绑定(bind)到一个 const ref)。

关于c++ - string_view 真的会导致释放后使用错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55790420/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com