Reputation: 210525
This question is related to, but not quite the same as, this question.
Are there any benefits to using std::vector<char>
instead of std::string
to hold arbitrary binary data, aside from readability-related issues?
i.e. Are there any tasks which are easier/more efficient/better to perform with a vector compared to a string?
Upvotes: 30
Views: 21196
Reputation: 3346
As other answers mention, a vector could be marginally faster since it guarantees contiguous memory, even for small sizes, and doesn't add an extra null byte at the end. However, it is a lot simpler (code-wise) to concatenate two strings than it is to concatenate two vectors:
Using vector
:
vector<char> a, b;
// ...
vector<char> c;
c.insert(c.end(), a.begin(), a.end());
c.insert(c.end(), b.begin(), b.end());
Using string
:
string a, b;
// ...
string c = a + b;
Upvotes: 1
Reputation: 210525
vector<char>
indeed does have more capabilities over string
.Unlike string
, vector<char>
is guaranteed to preserve iterators, references, etc. during a swap
operation. See: May std::vector
make use of small buffer optimization?
Upvotes: 2
Reputation: 13192
Aside from readability (which should not be underestimated) I can think of a couple of minor performance/memory issues with using std::string
over std::vector
:
Some modern std::string
implementations use the small string optimization. If you are storing data that's larger than the string
's internal buffer, it becomes a pessimization, reducing the efficiency of copying, moving, and swap
1 and increasing the sizeof()
for no benefit.
An efficient std::string
implementation will always allocate at least 1 more byte than the current size for storing a terminating null (not doing so requires extra logic in operator[]
to cope with str[size()]
).
I should stress that both of these issues are very minor; the performance cost of them will more than likely be lost in the background noise. But you did ask.
1Those operations require branching on size()
if the small string optimization is being used, whereas they don't in a good std::vector
implementation.
Upvotes: 28
Reputation: 1490
Ideally one would use vector<unsigned char>
to store arbitrary binary data - but I think you already knew this - as you referred to the old question.
Other than that, using vector would definitely be more memory efficient, as string would add a terminating Nul character. Performance might also improve as the allocation mechanism is different for both - vectors guarantee contiguous memory!
Besides that, using a string would not be correct, as callers/users might inadvertently invoking some of the string methods, which could be a disaster.
Upvotes: 0
Reputation: 17524
Beyond readability, and ensuring another maintainer does not confuse the purpose of the std::string
, there is not a lot of difference in function. You could of course consider char*/malloc as well, if efficiency is the only consideration.
One potential issue I can think of:
std::string
defaults to storing <char>
. If you later needed to handle another type (e.g. unsigned short) you might need to either:
std::basic_string<unsigned short>
(which moves you away from normal std::string
handling)With a vector you could simply change the container to a std::vector<unsigned short>
.
Upvotes: 1
Reputation: 1080
I think the only benefit you would gain from doing that would the ease of incrementing over the std::vector
of characters, but even that can be done with an std::string
.
You have to remember that even though std::string
seems like an object, it can be accessed like an array, so even accessing specific parts of a string can be done without the use of a std::vector
Upvotes: 0