6

i need a std::string of size bytes, after constructing it i am going to write to every byte in that string prior to reading from it, thus null-initializing the string is a waste of cpu, this works:

std::string s(size,0);

but it's just slightly wasteful, it's basically like using calloc() when all i need is malloc(), so the question is, how do i construct a string of X uninitialized bytes?

(using reserve()+push is not an option because im giving the string to a C-api taking char*,size to do the actual initialization)

edit: this thread seems to about the same issue/related (but with vectors instead of strings): Value-Initialized Objects in C++11 and std::vector constructor

hanshenrik
  • 19,904
  • 4
  • 43
  • 89
  • If its about optimization, and only malloc() is efficient enough, why not use it? It is not like it`s forbidden. – RoQuOTriX Apr 23 '20 at 08:13
  • Perhaps `std::string` isn't the correct choice here? Perhaps you should be using a plain array (possibly dynamically allocated) instead? You can always put it into a `std::string` (or `std::string_view`) later. – Some programmer dude Apr 23 '20 at 08:14

1 Answers1

5

You can't do it with std::string. But it can be achieved different way, like using std::unique_ptr<char[]>.

auto pseudo_string = std::unique_ptr<char[]>(new char[size]);

Or if your compiler supports C++20

auto pseudo_string = std::make_unique_for_overwrite<char[]>(size);
bartop
  • 9,971
  • 1
  • 23
  • 54
  • 1
    Wouldn't all the elements of the array be value-initialized by [`std::make_unique`](https://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique)? – songyuanyao Apr 23 '20 at 08:42
  • @songyuanyao take a look at your own link overload (2) and (5) – bartop Apr 23 '20 at 08:50
  • 2
    It appears a that c++20 introduces `std::make_unique_for_overwrite` to do just this. – eerorika Apr 23 '20 at 08:52
  • 1
    @bartop ? Then shouldn't `make_unique_for_overwrite` be used instead? – songyuanyao Apr 23 '20 at 08:53
  • it's a compelling alternative and i have upvoted your post, but i think it may be possible with std::string() nontheless, because std::string default constructor accepts a `const allocator_type& allocator` if you want to use a custom allocator, and i think the default string constructor depends on the allocator to do the null-initialization, thus i think it would be possible to supply a custom allocator that simply doesn't initialize... i haven't actually tried it though, just speculation at this point. anyway thanks for the alternative! – hanshenrik Jun 11 '20 at 08:37