IBM i 上 std::vector<std::string> 的最大容量

Maximum capacity of std::vector<std::string> on IBM i

最近我发现在 ibm i 上调整 std::vector 的奇怪行为。 所以,当你定义

std::vector<std::string> vec;

系统 returns vec.max_size();

约 87M

然而,当我这样做时:

vec.reserve(400000); 甚至更多失败,没有内存异常 及对应查询:Signal SIGABRT raised (abnormal termination).

我终于发现 300k 是某种字符串向量的阈值,用于 运行.

这是日志:

Procedure:          _CXX_PEP__Fv                                                                                                   
      TESTPGM      TESTLIB      7                                       CALLER     0000000000000036 TESTPGM      QTEMP        Н      
Procedure:          main
      TESTPGM      TESTLIB      4                                       CALLER     0000000000000036 TESTPGM      QTEMP        Н      
Procedure:          reserve__Q2_3std6vectorXTQ2_3std12basic_stringXTcTQ2_3std11char_traitsXTc_TQ2_3std9allocatorXTc__TQ2_3std9allo 
torXTQ2_3std12basic_stringXTcTQ2_3std11char_traitsXTc_TQ2_3std9allocatorXTc____FUi                                                 
      TESTPGM      TESTLIB      1                                       CALLER     0000000000000036 TESTPGM      QTEMP        Н      
Procedure:          allocate__Q2_3std9allocatorXTQ2_3std12basic_stringXTcTQ2_3std11char_traitsXTc_TQ2_3std9allocatorXTc___FUiPCv   
      TESTPGM      TESTLIB      1                                       CALLER     0000000000000036 TESTPGM      QTEMP        Н      
Procedure:          _Allocate__3stdHQ2_3std12basic_stringXTcTQ2_3std11char_traitsXTc_TQ2_3std9allocatorXTc___UiPQ2_3std12basic_str 
gXTcTQ2_3std11char_traitsXTc_TQ2_3std9allocatorXTc___PQ2_3std12basic_stringXTcTQ2_3std11char_traitsXTc_TQ2_3std9allocatorXTc__     
      QYPPRT370  QSYS         12                                        CALLER     0000000000000036 NWSCTODF37 QBUILDSS1    Н      
Procedure:          __nw__FUi                                                                                                      
      QYPPRT370  QSYS         2                                         CALLER     0000000000000036 NOMEMORY37 QBUILDSS1    Н      
Procedure:          _Nomemory__3stdFv                                                                                              
      QYPPRT370  QSYS         11                                        CALLER     0000000000000036 THROW37    QBUILDSS1    Н      
Procedure:          __Throw                                                                                                        
      QYPPRT370  QSYS         24                                        CALLER     0000000000000036 DOTHROW37  QBUILDSS1    Н
Procedure:          __DoThrow                                                                                                
      QYPPRT370  QSYS         16                                        CALLER     0000000000000036 EXCEPTIO37 QBUILDSS1    Н
Procedure:          terminate__3stdFv                                                                                        
      QYPPRT370  QSYS         1                                         CALLER     0000000000000036 EXCEPTIO37 QBUILDSS1    Н
Procedure:          myabort__3stdFv                                                                                          
      QC2UTIL1   QSYS         2                                         CALLER     0000000000000036 QC2TERM    QBUILDSS1    Н
Procedure:          abort                                                                                                    
      QC2UTIL1   QSYS         6                                         CALLER     0000000000000036 QC2SIGNL   QBUILDSS1    Н
Procedure:          raise                                                                                                    
      QMHPDEH    QSYS                                              012E *DFTACTGRP 0000000000000001                         Н
      QMHUNMSG   QSYS                                              0196 *DFTACTGRP 0000000000000001                         Н
      QMHAPD     QSYS                                              02EC *DFTACTGRP 0000000000000001                         Н

此作业已设置 CPUTIME *NOMAXMAXTMPSTG *NOMAX

所以,我想知道 ibm 是否限制了我使用 300k 元素向量,或者我在某处搞砸了。

或者 ibm 出于某种原因强迫我使用 vector of vectors?

我在 OS 7.3 TR5 如果重要的话

vactor::max_size() 只是给你理论值。

您是否可以实际为这么多元素分配内存将取决于运行时实际可用的内存。

我尝试了以下程序:

#include <vector>                      
#include <string>                      
int  main(void)                        
{                                      
  int i;                               
  std::vector<std::string> * vec;      
  i = vec->max_size();                 
  vec = new std::vector<std::string>;  

  vec->reserve(i);                     
  delete vec;                          
  return 0;                            
}                                      

I compiled as follows: 
CRTCPPMOD MODULE(TEST) DBGVIEW(*ALL) TERASPACE(*YES *TSIFC) STGMDL(*TERASPACE) 
  DTAMDL(*LLP64) RTBND(*LLP64)                                       
CRTPGM PGM(TEST) STGMDL(*TERASPACE) 

这表明 max_size returns 178,956,970,比您看到的值大得多。

但是,将其传递给 reserve() 会导致 sigabort 并终止作业!

我能够成功地将 89000000 传递给 reserve(),但是(用字符串填充向量很可能会导致崩溃!)

我不确定所有血淋淋的细节,但我怀疑这在很大程度上与堆的非 teraspace 实现(它将连续存储限制在大约 16MB)与 Teraspace 的限制是 4GB 的连续可寻址有关分配。您可以尝试我指定的选项,看看会发生什么。

注意我在堆中分配了向量。对于堆栈或静态分配的向量,情况可能有所不同。