Is there a way make a std::string that references an externally provided buffer but not own it?

1.5k Views Asked by At

Basically if one has a preloaded buffer for a null terminated string and the length to be referenced, and wants to pass a reference to it into a method that takes a std::string & but not copy the string or have it owned, is it possible to do so ?

This would only have a limited lifespan that is managed in such a way that it is only valid while the buffer is valid.

2

There are 2 best solutions below

3
Antoine Morrier On BEST ANSWER

Basically, the answer is no for the non owning string.

However, if the non owning criteria is not that important what you could do is to use your own allocator to reference a particular buffer.

What you also can do, is to use std::pmr::string which allows you to give a custom memory_resource.

The idea is as following :

#include <string>
#include <memory_resource>
#include <array>
#include <utility>
#include <iostream>

template<std::size_t size>
class StackBufferResource {
    public:
        auto as_resource() {return &m_resource;}
        auto address() {return m_buffer.data();}
    private:
        std::array<std::byte, size> m_buffer{};
        std::pmr::monotonic_buffer_resource m_resource{m_buffer.data(), size};
};

int main() {
    StackBufferResource<512> buffer;

    std::pmr::string myString("My name is Antoine and I am not sure for this answer", buffer.as_resource());
    std::cout << myString << "\n";
    std::cout << (const char*)buffer.address() << std::endl;
}

std::pmr::monotonic_buffer_resource is a memory_resource object which continually grows. It means that a deallocation is a kind of "no op".

What is nice with such a thing is that you can give the same thing to a std::pmr::vector.

However, you may pay the attention to the following points :

std::pmr::string use char. Since it is a trivial object, I think (I am not sure though) that it is safe to access the buffer memory after the string got destroyed. If it was a type not trivially destructible, I think it would be possible to see garbage values.

4
eerorika On

Is there a way make a std::string that references an externally provided buffer but not own it?

No.

You have these options:

  1. Use std::string as the "external" buffer in the first place.
  2. Copy the external buffer into the string.
  3. Don't use (reference to) std::string as the parameter.
    • std::string_view is a typically good choice. However, it's very easy to create non-null terminated string views, and your premise explicitly states null termination. If that's important, then you may need to avoid string view.
    • If string view isn't appropriate, then you can use const char* to point to the null terminated string.