Reputation: 31
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
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