Yan
Yan

Reputation: 31

Is it safe to pass a temporary std::string to a function accepting std::string_view?

I am working on a C++ program and have a question about the safety of passing a std::string to a function that accepts a std::string_view. Here is my code: i make some

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

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

In this example, I am creating a temporary std::string object and passing it to the foo function, which takes a std::string_view as a parameter. I understand that std::string_view is a non-owning reference to a string.

And here is another problem about a leetcode problem.

#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));

A string_view is created from nums[i] using string_view(nums[i]), and then substr(nums[i].size() - t) is used to extract the last t characters. Why is string_view(nums[i]) necessary? Couldn’t we just call substr directly on nums[i] without creating a string_view?

My question is: Is it safe to pass a temporary std::string to a function that takes a std::string_view? Will the lifetime of the temporary std::string be extended for the duration of the function call, or is there a potential for undefined behavior?

I would appreciate a detailed explanation of how std::string_view interacts with temporary objects, and any best practices to avoid potential issues.

Upvotes: 1

Views: 152

Answers (1)

Marshall Clow
Marshall Clow

Reputation: 16660

Is this code safe?

It depends.

Specifically, it depends on what foo does. If foo retains a copy/reference to sv or to any of the characters referenced by sv, then that would not be safe.

Example code (untested)

string_view global_sv;

void foo(std::string_view sv) {
    global_sv = sv;
}

After foo returns, global_sv references a destructed string.

If, on the other hand, foo does not retain any references/copies, then the code is fine, because the string that sv is referencing is not destroyed until the end of the expression (i.e, after foo has returned)

void foo(std::string_view sv) {
    std::cout << sv << std::endl;
}

Upvotes: 6

Related Questions