title: How to get real max size of stringstream without write anything into it?
body: <p>I am dealing big libpacp files with the program below.</p>
  
  <p>I am confused about the real max size of memory that stringstream can allocate from the OS.</p>
  
  <p>The first part of code is the program for processing libpacp files.</p>
  
  <p>The second part is the program for testing.</p>
  
  <p><strong>Environment:</strong> Windows 10, VS, complied in Win32-Released(32-bit) mode.</p>
  
  <p><strong>First Part:</strong></p>
  
  <pre><code>#include &lt;fstream&gt;
  #include &lt;iostream&gt;
  #include &lt;sstream&gt;
  #include &lt;string&gt;
  #include &lt;ctime&gt;
  #include &lt;cstdio&gt;
  
  #define HeaderBytes 24
  #define MaxPkgBytes 65544  //65536+8
  #define KeepDays 7
  #define KeepSeconds (KeepDays*86400)
  #define StartTimeOffset (-1*86400)  // -1 day
  
  using namespace std;
  
  typedef struct{
      int size;
      char data[MaxPkgBytes];
  }pkg;
  
  int catoi(const char* ca){
      char tmp[4];
      int* iptr;
      for (int i = 0; i &lt; 4; i++){
          tmp[i] = ca[3 - i];
      }
      iptr = reinterpret_cast&lt;int*&gt;(tmp);
      return *iptr;
  }
  
  #ifdef _MSC_VER
  #include &lt;windows.h&gt;
  #include &lt;iomanip&gt;
  wstring str2wstr(const std::string&amp; s)
  {
      int len;
      int slength = (int)s.length() + 1;
      len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
      wchar_t* buf = new wchar_t[len];
      MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
      wstring wstr(buf);
      return wstr;
  }
  #endif // _MSC_VER
  
  
  int main(int argc, char** argv){
      string inFileName, outFileName;
      stringstream outBuf;
      fstream fs_in, fs_out;
      char buf_char;
      int buf_int, headercount = 0, curPkgIdx= 0, lastPkgIdx = 1, tmp;
      bool isBroken = false, isValid;
      clock_t mytime;
      unsigned int StartTime = 0, PkgTime;
      pkg buf_pkg[2];
  
      if (argc != 2){
          return 1;
      }
  
  
      inFileName = argv[1];
      fs_in.open(inFileName, ios::binary | ios::in);
      if (!fs_in){
          cout &lt;&lt; "Can't open the file: " &lt;&lt; inFileName &lt;&lt; endl;
          return 1;
      }
  
      outFileName = inFileName;
      outFileName.insert(outFileName.rfind('.'), "_integrated");
      fs_out.open(outFileName, ios::binary | ios::out);
      if (!fs_out){
          cout &lt;&lt; "Can't open the file: " &lt;&lt; outFileName &lt;&lt; endl;
          return 1;       
      }
  
  
      int invalidPConuter = 0;
      long long outBufMaxPos = 0;
  
  
      buf_pkg[0].size = 0;
      buf_pkg[1].size = 0;
  
      mytime = clock();
      fs_in.read(buf_pkg[curPkgIdx].data, HeaderBytes);
      outBuf.write(buf_pkg[curPkgIdx].data, HeaderBytes);
      if (fs_in){
          fs_in.read(buf_pkg[curPkgIdx].data, 4);
          StartTime = catoi(buf_pkg[curPkgIdx].data);
          StartTime += StartTimeOffset;
          fs_in.seekg(-4, ios_base::cur);
      }
      cout &lt;&lt; "start" &lt;&lt; endl;
      while (fs_in.get(buf_char)){
          fs_in.seekg(-1, ios_base::cur);
          if (buf_char == -95 ){    //0xa1
              fs_in.read(reinterpret_cast&lt;char*&gt;(&amp;buf_int), sizeof(int));
              if (buf_int == 0xd4c3b2a1){  //a1b2 c3d4
                  fs_in.seekg(HeaderBytes-4, ios_base::cur);
                  headercount++;
              }
              else fs_in.seekg(-4, ios_base::cur);
          }
          else{
              fs_in.read(buf_pkg[curPkgIdx].data, 16);
              PkgTime = catoi(buf_pkg[curPkgIdx].data);
  
              /*Set isValid*/
              if (PkgTime - StartTime &lt; KeepSeconds) isValid = true;
              else isValid = false;
  
              if (isValid){  //last packetage is valid
                  /*store size of packetage*/
                  buf_pkg[curPkgIdx].size = catoi(buf_pkg[curPkgIdx].data + 8);
                  /*store size of packetage*/
                  if (buf_pkg[curPkgIdx].size &gt; MaxPkgBytes) isValid = false;
              }
              if (isValid) //Pass packet size check
              {
                  /*read packetage data*/
                  fs_in.read(buf_pkg[curPkgIdx].data + 16, buf_pkg[curPkgIdx].size);
                  buf_pkg[curPkgIdx].size += 16;
                  /*read packetage data*/
  
                  /*write last packetage data*/
                  outBuf.write(buf_pkg[lastPkgIdx].data, buf_pkg[lastPkgIdx].size);
                  if (static_cast&lt;long long&gt;(outBuf.tellp()) &gt; outBufMaxPos)
                  {
                      outBufMaxPos = static_cast&lt;long long&gt;(outBuf.tellp());
                  }
                  else if (static_cast&lt;long long&gt;(outBuf.tellp()) == -1)
                  {
                      cout &lt;&lt; "outBufMaxPos: " &lt;&lt; outBufMaxPos &lt;&lt; endl;
                      system("pause");
                  }
  
                  if (outBuf.tellp() &gt;= 0x40000000 - MaxPkgBytes) // 1GB
                  {
                      cout &lt;&lt; "write" &lt;&lt; endl;
                      fs_out &lt;&lt; outBuf.rdbuf();
                      outBuf.str("");
                      outBuf.clear();
                  }
                  /*write last packetage data*/
  
                  /*swap idx of buffer*/
                  tmp = curPkgIdx;
                  curPkgIdx = lastPkgIdx;
                  lastPkgIdx = tmp;
                  /*swap idx of buffer*/
              }
              if (!isValid)
              {
                  ++invalidPConuter;
                  isBroken = true;
                  fs_in.seekg(-buf_pkg[lastPkgIdx].size - 15, ios_base::cur);
  
                  /*search correct packetage byte by byte*/
                  int tmpflag = 0;
  
                  /*Let PkgTime be invalid.
                  If packet is invalid because of its size, original PkgTime was valid*/
                  PkgTime = StartTime + KeepSeconds; 
  
                  while (PkgTime - StartTime &gt;= KeepSeconds &amp;&amp;             fs_in.read(buf_pkg[curPkgIdx].data, 4)){
                      PkgTime = catoi(buf_pkg[curPkgIdx].data);
                      fs_in.seekg(-3, ios_base::cur);
                  }
                  fs_in.seekg(-1, ios_base::cur);
                  /*search correct packetage byte by byte*/
  
                  buf_pkg[lastPkgIdx].size = 0; //reset the size of the invalid packetage
              }
          }
      }
      fs_in.close();
  
      mytime = clock() - mytime;
      cout &lt;&lt; "Repair pacp: " &lt;&lt; mytime &lt;&lt; " miniseconds." &lt;&lt; endl;
      cout &lt;&lt; "Number of deleted headers: " &lt;&lt; headercount &lt;&lt; endl;
  
  
      mytime = clock();
  
      if (headercount || isBroken){
          fs_out &lt;&lt; outBuf.rdbuf();
          fs_out.close();
  #ifdef _MSC_VER
          wstring originFileName, newFileName;
          originFileName = str2wstr(inFileName);
          newFileName = str2wstr(inFileName.insert(inFileName.rfind("."), "_origin"));
  
          int flag = MoveFileExW(originFileName.c_str(), newFileName.c_str(), 0);
          if (!flag)
          {
              cout &lt;&lt; "fail to rename origin file" &lt;&lt; endl;
              cout &lt;&lt; showbase // show the 0x prefix
                  &lt;&lt; internal // fill between the prefix and the number
                  &lt;&lt; setfill('0'); // fill with 0s
              cout &lt;&lt; "Error code: " &lt;&lt; hex &lt;&lt; setw(4) &lt;&lt; GetLastError() &lt;&lt; dec &lt;&lt; endl;
          }
          else
          {
              newFileName = originFileName;
              originFileName = str2wstr(outFileName);
              flag = MoveFileExW(originFileName.c_str(), newFileName.c_str(), 0);
              if (!flag)
              {
                  cout &lt;&lt; "fail to rename output file" &lt;&lt; endl;
                  cout &lt;&lt; showbase // show the 0x prefix
                      &lt;&lt; internal // fill between the prefix and the number
                      &lt;&lt; setfill('0'); // fill with 0s
                  cout &lt;&lt; "Error code: " &lt;&lt; hex &lt;&lt; setw(4) &lt;&lt; GetLastError() &lt;&lt; dec &lt;&lt; endl;
              }
          }
  
  #endif //_MSC_VER       
  
      }
      else
      {
          wstring tmpwstr = str2wstr(outFileName);
          fs_out.close();
          if (!DeleteFileW(tmpwstr.c_str()))
          {
              cout &lt;&lt; "Cannot deleted tmp file (integrated)" &lt;&lt; endl;
          }
          cout &lt;&lt; "The file is completed. Do nothing." &lt;&lt; endl;
      }
  
      mytime = clock() - mytime;
      cout &lt;&lt; "Rename file: " &lt;&lt; mytime &lt;&lt; " miniseconds." &lt;&lt; endl;
      system("pause"); 
      return 0;
  
  }
  </code></pre>
  
  <p><strong>Pseudo code of the first part:</strong></p>
  
  <pre><code>using namespace std;
  
  int main(int argc, char** argv){
      //leave over the varibles
      string inFileName, outFileName;
      fstream fs_out;
      char buf_char;
      int buf_int, headercount = 0, curPkgIdx= 0, lastPkgIdx = 1, tmp;
      bool isBroken = false, isValid;
      clock_t mytime;
      unsigned int StartTime = 0, PkgTime;
      pkg buf_pkg[2];
      int invalidPConuter = 0;
      long long outBufMaxPos = 0;
  
      //the varibles will be mentioned
      fstream fs_in;
      stringstream outBuf;
  
      fs_in.read(Header);
      outBuf.write(Header);
  
      if (fs_in){
          StartTime = first_packet_time + StartTimeOffset;
      }
  
      while (!fs_in.eof()){
          if (a header read from fs_in){ 
              skip the block of header
          }
          else{
              fs_in.read(packet header);
  
              if (time of packet isValid){
                  check size of packet
              }
              if (size and time isValid)
              {
                  fs_in.read(packet data);  
                  outBuf.write(packet data);
  
                  if(outBuf out of range)
                  {
                      print(max stringstream size)
                      system("pause");
                  }               
  
                  if (outBuf size &gt;= 1GB)
                  {
                      write outBuf into output file
                  }
              }
              if (size or time isNotValid)
              {
                  find next valid packet byte by byte
              }
          }
      }
      fs_in.close();
  
      system("pause"); 
      return 0;
  }
  </code></pre>
  
  <p><strong>Second Part:</strong></p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;typeinfo&gt;
  #include &lt;sstream&gt;
  #include &lt;string&gt;
  
  using namespace std;
  
  
  #define testsize (80*1024*1024)
  int main()
  {
      stringstream ss;
      char* buf = new char[testsize];
      int i = 0;
      memset(buf, 'a', testsize);
      while (i &lt; 30)
      {
          ss.write(buf, testsize);
          cout &lt;&lt; ss.tellp()/1024/1024 &lt;&lt; endl;
          ++i;
      }
      system("pause");
  }
  </code></pre>
  
  <p>In the first part, the stringstream's max size is limited to about 674MB.</p>
  
  <p>But in the second part, stringstream's max size is limited to about 2GB.</p>
  
  <p>Why they are different?</p>
  
  <p>And how can I get real max size of stringstream without write anything into it?</p>
  
  <p>I have searched related problem, but the answers didn't help me.</p>