大多维向量初始化c++
Big multidimensional vector initializaton C++
我正试图将模拟结果从文件加载到矢量中。该代码适用于中小型数据量。当我尝试加载大文件时,我得到一个异常。让我的程序崩溃的数组大约是17000*7*3000个元素。我试过将初始化分成几个步骤,但它也崩溃了。你能告诉我我能做些什么让它起作用吗?
//////////////////////////////////////////////////////////
//Import of surface receivers file
for(int freq=0;freq<7;freq++)
{
filePath=filePath_old;
filePath.Replace(wxT("125 Hz"),wxString::Format(wxT("%i"), freqSTI[freq])+wxT(" Hz"));
if(importer.ImportBIN(filePath,mainData))
{
if(timeTable.size()==0){
for(int idstep=0;idstep<mainData.nbTimeStep;idstep++)
{
timeTable.push_back(mainData.timeStep*(idstep+1)*1000);
}
}
for(wxInt32 idrs=0;idrs<mainData.tabRsSize;idrs++)
{
for(wxInt32 idface=0;idface<mainData.tabRs[idrs].dataRec.quantFaces;idface++)
{
if(tab_wj.size()<idrs+1){
tab_wj.push_back(std::vector<std::vector<std::vector<wxFloat32> > > (mainData.tabRs[idrs].dataRec.quantFaces,std::vector<std::vector<wxFloat32> >(7,std::vector<wxFloat32>(mainData.nbTimeStep,0.f))));
}
//Pour chaque enregistrement de cette face
int tmp=mainData.tabRs[idrs].dataFaces[idface].dataFace.nbRecords;
for(wxInt32 idenr=0;idenr<mainData.tabRs[idrs].dataFaces[idface].dataFace.nbRecords;idenr++)
{
t_faceValue* faceval=&mainData.tabRs[idrs].dataFaces[idface].tabTimeStep[idenr];
tab_wj[idrs][idface][freq][faceval->timeStep]=faceval->energy;
}
}
}
}
}
发生异常的地方是tab_wj.push_back...
当我试图将初始化拆分为多个步骤时,我写:
std::vector<wxFloat32> t1(mainData.nbTimeStep,0.f);
std::vector<std::vector<wxFloat32> > t2(7,t1);
std::vector<std::vector<std::vector<wxFloat32> > > t3(mainData.tabRs[idrs].dataRec.quantFaces,t2);
最后一行崩溃了。
谢谢你的帮助!
看起来在分配内存时遇到了异常。Std::vector<>必须在向其添加新项时重新分配其存储空间。它不会对每个push_back()都这样做,因为它分配的比需要的多。大小为5的vector<>实际上可能有8个项目的空间(size() vs. capacity())。当您插入第9项时,它必须重新分配,通常它的容量将翻倍(从8到16(*))。
这种重新分配可以分割堆。为了改进,您可以预先分配向量到它最终需要的大小,这样它就永远不需要重新分配。向量:储备()因此,如果您知道最终需要17000*7*3000,请预先预留。
同样,如果你有很多小的向量,分配一个小的大小可以减少你的内存需求。通常vector<>有一个默认大小,可以是8或16。如果你只插入3个条目,那么你就浪费了大量的存储空间。在分配矢量时,我相信您可以指定它的初始容量。
由于您使用的是嵌套向量,因此它们中的每一个都将依次拥有自己的分配。根据c++版本的不同,将vector压入vector上可能会导致大量的赋值操作。
你可以尝试重构代码,使其不需要嵌套向量。
(*):一个朴素的向量实现在需要更多空间时将分配大小加倍,但1.6的系数更好,原因有很多(它的效率和大0一样高,导致更少的内存碎片)。参见"黄金分割率":https://en.wikipedia.org/wiki/Golden_ratio
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 为什么在C++中首先初始化成员类
- 同时具有"聚合初始化"和"模板推导"
- 初始化具有非默认构造函数的std::数组项的更好方法
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 在C和C++中初始化结构中的数组
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 在函数内部的声明中初始化数组,并在外部使用它
- 继承:构造函数,初始化C++11中基类的类C数组成员