- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
根据一篇文章(here 和 there),这段代码是一个错误的免费示例:
#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/
假设我们有一个 string_view 和另一个 string_view,它是第一个 string_view 的子集: using namespace std; // just to shorten
我正在使用一个使用 boost::string_view 的 boost 库。但是,我想在我的代码中使用 std::string_view。 问:在这两者之间进行转换的最佳方式是什么? 目前我正在使用
std::string_view::remove_prefix() 和 std::string_view::remove_suffix() 都是 c 中的 constexpr 成员函数++17;但是,
我已经从 Bjarne Stroustrup 的 A Tour of C++ 中复制代码来测试字符串 View ,但我不断收到错误: error: no matching function for c
除了 std::string_view 方法之外,std::string_view 是否比 char* 有任何优势? 如果没有使用 string_view 的方法,是否有任何理由将 char* 重构为
我有这个循环: for (const std::string_view resource : resources) { ... } 由此资源被定义为 inline const std::string_
我有这个循环: for (const std::string_view resource : resources) { ... } 由此资源被定义为 inline const std::string_
而一个 span可以从一个范围构建,一个 string_view不能从一系列字符构造。 因此,例如,需要以下代码: // assume chars_span is a span of chars st
void Foo1(string_view view) { ... } string str = "one two three"; Foo1("one two three"); // Implicit
我有一个字符串,其中包含用 , 字符分隔的数字序列。为了将序列中的值读入数组,我创建了以下 GCC 10 拒绝编译的代码: #include #include #include #include
我在使用 Boost 1.70 时发现了一个相当令人费解的问题,有时 boost::string_view 似乎指向另一个字符串。 这是创建 boost::string_view 的函数调用,如下所示
在以下场景中使用 std::string_view: struct A : public std::exception{ A (const char* c) : v_(c){} con
我正在尝试尽可能多地使用 std::string_view 来包装 C 字符串,但是,每当我正在包装的 C 字符串被动态分配时,我都依赖于此图案: char *cs = get_c_string();
我读了The most elegant way to iterate the words of a string并享受答案的简洁性。现在我想对 string_view 做同样的事情。问题是,strin
我有以下代码: #include class Foo { public: Foo(std::string_view) {} }; 当我这样做时,一切都可以正常编译(使用 clang v8,C
根据一篇文章(here 和 there),这段代码是一个错误的免费示例: #include #include #include int main() { std::string s = "H
string_view 是 C++ 库基础 TS(N3921) 中的一项提议功能,添加到 C++17 据我所知,它是一种代表某种字符串“概念”的类型,它是任何类型的容器的 View ,可以将可视内容存
考虑以下代码: #include #include int main() { std::optional opt { "abc" }; std::cout { std::stri
在 std::string_view 上匹配正则表达式工作正常。但是当我返回匹配的子字符串时,它们会因为某种原因而消失。 std::string_view 参数在函数作用域结束时被销毁,但它指向的内存
This reference指出第二个示例产生了一个悬空指针。如何在第二个表达式中创建悬挂指针而不是在第一个表达式中? std::string_view good("a string literal"
我是一名优秀的程序员,十分优秀!