Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

implementation of shrink_to_fit for string and vector are different?

Tags:

c++

I called shrink_to_fit() for vector and it reduced the capacity to number of elements in vector but when I used shrink_to_fit() for string , it reduced the size but its not the number of elements in string .

#include <iostream>
#include<vector>
#include<cstring>
using namespace std;
int main()
{
   vector<char> v1;
   v1.reserve(20);
   v1.push_back('a');
   v1.push_back('b');
   cout << " vector capacity= "<<v1.capacity() <<endl;
   v1.shrink_to_fit();
   cout << " changed vector capacity= "<<v1.capacity() <<endl;

   string s1;
   s1.reserve(20);
   s1.push_back('a');
   s1.push_back('b');
   cout <<" string capacity = " << s1.capacity() <<endl;
   s1.shrink_to_fit();
   cout <<" changed string capacity = " << s1.capacity() <<endl;

}

OUTPUT :

  vector capacity= 20
  changed vector capacity= 2
  string capacity = 30
  changed string capacity = 15
like image 499
Alok Avatar asked May 06 '18 23:05

Alok


1 Answers

Modern implementations of std::string generally provide "short string optimization", which means that strings under a certain length don't require a separate allocation, but are stored inside the std::string object itself (typically in the space that would be used for some of the pointers). So, this means that you cannot get less capacity than - in your case - 15 (which rings right, as that's 16 with the NUL terminator, and that's two 64 bit pointers), as it's stored straight in the string object, when there's no longer anything else to deallocate.

Besides, you are comparing apples to oranges; nothing stops std::vector from implementing a similar optimization for smaller types¹, but you are comparing a std::vector<int> (whose elements are generally 4 bytes, so only 4 would fit in the aforementioned 16 bytes) with a std::string (whose elements are 1-byte char). A more proper comparison would be against std::vector<char>.


  1. actually, as pointed out in the comments, the current standard places requirements incompatible with such an optimization; still, the main point stands: when comparing two containers, you should do so making sure that the "boundary conditions" are the same, so you can spot the actual implementation differences (std::string does SSO, std::vector<char> doesn't) without being distracted by differences that arise from the fact that you are comparing them against different problems.
like image 119
Matteo Italia Avatar answered Sep 20 '22 01:09

Matteo Italia