0

I'm trying to use std::string_view as much as I can to wrap C-string, however, whenever the C-string I'm wrapping is dynamically allocated, I rely on this pattern:

char *cs = get_c_string();
std::string s(cs);
free(cs);

which is a waste of time because it involves 1 allocation, 1 copy and 1 deallocation.

Is there a way to do this better ? Or do I need to write my own string_view wrapper ?

Praetorian
  • 106,671
  • 19
  • 240
  • 328
Benoît
  • 3,355
  • 2
  • 29
  • 34
  • 2
    How you deal with the ownership of the memory behind a `string_view` is entirely up to you. That's the whole point of the type; the code taking it doesn't care about how it's owned. – Nicol Bolas Oct 03 '17 at 18:11
  • 1
    How about managing the string's lifetime using a `unique_ptr` and custom deleter, and create `string_view`s from it as needed? You could wrap this up in some custom type that saves the length of the c-string to avoid having to compute it every time you create a `string_view`. – Praetorian Oct 03 '17 at 18:18
  • _whenever_ also known as seldom. –  Oct 03 '17 at 21:09
  • @manni66 Do you know what C libraries the OP is using? Maybe it’s not good style, but that doesn’t mean it’s seldom in their codebase. – Daniel H Oct 10 '17 at 14:18

1 Answers1

4

string_view does not have any ownership semantics whatsoever. If you want to take ownership of it, use a smart pointer.

std::unique_ptr<char, decltype(&std::free)> cs(get_c_string(), std::free);

Or:

template <auto Deleter>
struct FuncDeleter {
    template <class P>
    void operator()(P* p) const { Deleter(p); }
};

std::unique_ptr<char, FuncDeleter<std::free>> cs(get_c_string());
Barry
  • 286,269
  • 29
  • 621
  • 977
  • Can't `std::free`'s type be deduced, since we are talking about [tag:c++1z]? – Zereges Oct 03 '17 at 18:21
  • @Zereges From what? – Barry Oct 03 '17 at 18:21
  • `std::unique_ptr cs(get_c_string(), std::free);` into `std::unique_ptr cs(get_c_string(), std::free);` or even `std::unique_ptr cs(get_c_string(), std::free);` – Zereges Oct 03 '17 at 18:22
  • 2
    @Zereges There's no class template argument deduction for `std::unique_ptr`... and even if there were, the first thing you suggest wouldn't work because there's never any partial class template argument deduction. – Barry Oct 03 '17 at 18:23
  • It’s difficult to use a `unique_ptr` as a string in C++. You’d need to at least make a `string_view` as well for it to be usable, and if you wanted to change ownership you’d need to pass both around. Although it would work slightly better if you made it a `unique_ptr` instead. – Daniel H Oct 10 '17 at 14:22