我如何安全地使用std::string_view?

问题描述 投票:0回答:1

标题:将临时 std::string 传递给接受 std::string_view 的函数是否安全?

身体:

我正在开发一个 C++ 程序,并且对将 std::string 传递给接受 std::string_view 的函数的安全性有疑问。这是我的代码: 我做了一些

#include<bits/stdc++.h>
using namespace std;
void foo(string_view sv) {
    
}

int main() {
    foo(string("abc"));//is it safe?
    return 0;
}

在此示例中,我创建一个临时 std::string 对象并将其传递给 foo 函数,该函数采用 std::string_view 作为参数。我知道 std::string_view 是对字符串的非拥有引用。

这是另一个关于 leetcode 问题的问题。

#include<ranges>

class Solution {
public:
    vector<int> smallestTrimmedNumbers(vector<string> &nums, vector<vector<int> > &queries) {
        vector<int> ans;
        auto cmp = [&](auto &a, auto &b) {
            if (a.first == b.first) return a.second < b.second;
            return a.first < b.first;
        };
        for (auto &&q: queries) {
            int k = q[0], t = q[1];
            vector<pair<string_view, int> > p;
            for (int i = 0; i < nums.size(); ++i) {
                p.push_back(make_pair(string_view(nums[i]).substr(nums[i].size() - t), i));
            }
            ranges::nth_element(p, p.begin() + k - 1, cmp);
            ans.push_back(p[k - 1].second);
        }
        return ans;
    }
};
p.push_back(make_pair(string_view(nums[i]).substr(nums[i].size() - t), i));

使用 string_view(nums[i]) 从 nums[i] 创建 string_view,然后使用 substr(nums[i].size() - t) 提取最后 t 个字符。为什么需要 string_view(nums[i]) ?难道我们不能直接在 nums[i] 上调用 substr 而不创建 string_view 吗?

我的问题是: 将临时 std::string 传递给采用 std::string_view 的函数是否安全?临时 std::string 的生命周期是否会在函数调用期间延长,或者是否有可能出现未定义的行为?

我希望详细解释 std::string_view 如何与临时对象交互,以及避免潜在问题的任何最佳实践。

c++ c++17 lifetime string-view
1个回答
0
投票

将临时 std::string 传递给 std::string_view 是不安全的,因为临时字符串被破坏,使 std::string_view 带有悬空引用。确保字符串的寿命足够长,以使 std::string_view 有效。

示例

void foo(std::string_view sv) {
// Do something with sv
}
    
int main() {
foo(std::string("abc"));  // Unsafe: temporary string is destroyed after this line
}

更安全的方法

int main() {
    std::string name = "abc";  // Safe: 'name' has a longer lifetime
    foo(name);  // Safe: 'name' is valid for the entire scope of foo()
    return 0;
}

string_view 的工作

  1. 原始字符串的任何变化都会直接反映在string_view中,因为string_view直接指向字符串内存地址。

  2. string_view 中的任何更改都不会反映在原始字符串中,它会创建自己的视图,并且会在其中进行更改,而不是原始字符串。

所以总而言之,直接将字符串传递给 string_view 是不安全的,因为它会一直存在,直到该行执行之后它才无效,因此最好在传递字符串之前声明该字符串,以便在函数调用后生命仍然存在。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.