3

Is it possible in theory to have a memory efficient STL (and/or Boost) vector of strings using some allocators such that:

using String = std::basic_string<char, std::char_traits<char>, SomeAllocMaybe;
using Vector = std::vector<String, SomeOtherAllocMaybe>;

Vector vec( /* an allocator eventually */ );
vec.emplace_back("first string longer than SSO");
vec.emplace_back("second string");
vec.emplace_back("third string longer than SSO");

Will result in having in memory only one compact contiguous block of data like this:

"first string longer than SSO'\0'second string'\0'third string longer than SSO'\0'"
5
  • 3
    and in your scenario what happens when you do vec[1].append("boom")? Commented Oct 9, 2019 at 9:33
  • 1
    this isnt really a vector, more like a concatenated string, and this already exitsts, it is std::string ;) Commented Oct 9, 2019 at 9:39
  • 1
    In theory, sure. However, this requires too many assumptions about how compilers implement std::string. If you really need the memory layout you've specified, it's probably worth rolling your own class for it. GCC for example: stackoverflow.com/q/5058676/5343120 Commented Oct 9, 2019 at 9:40
  • It is possible in theory, yes. But what is your need really ? do you just need the strings to be lying around in the same memory segment or do you wan't to avoid 'the pointer deref' as well ? In the first case - appending to a string might then move to different memory segment. Commented Oct 9, 2019 at 9:42
  • Using STL/Boost would take a lot of assumptions about the underlying implementation of those classes. I would rather implement it myself. Commented Oct 9, 2019 at 9:57

3 Answers 3

2

You can do that using boost interprocess allocators.

Sign up to request clarification or add additional context in comments.

1 Comment

Can you be more specific? Looks like there are many different types of facilities in the library, and different ways to compose them.
2

No, this is not possible with a std::vector and a std::basic_string. A std::vector holds a contiguous sequence of elements (std::basic_strings), and std::basic_string is not going to be laid out in memory in this particular way. It stores the size information, or at least the tag bit to differentiate long strings and short strings.

If you want the contiguous memory, directly use one std::basic_string instead. Appending one character to strings is of amortized constant time complexity, and thus concatenating strings will be efficient.

1 Comment

I think I can be fine if between strings there are some small additional information. Cannot say the same about having the whole SSO block between them, but let's assume it is fine as well.
0

Yes, that is definately possible - that being said, you probably do not wan't the same allocator/memory segment for both as it complicates things - mainly that when the vector needs reallocation you would have to move plus possible reallocate everything. Therefore you would need to take special care which again you would need to tailer into your specific need. So it's a lot simpler to just consider the strings heap alone and then you do not need to worry about the configure to your needs part. Im assuming the strings needs to be worked with with and aren't just const - because that is special case that could be handled very differently.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.