我需要C中的大型数组来存储一些数据。我正在研究的事情与DNA测序有关。我正在使用Visual Studio 2013。
首先,我尝试使用像
这样的全局静态变量static oligo SPECTRUM[C1][C2]
寡核苷酸结构含有8个整数,C1为100000和C2 500。
但是视觉上说阵列很大。然后我问Google,他说使用矢量是个好主意。所以我通过用下面的代码替换上面的代码来切换到这些
static std::vector<std::vector<oligo>> SPECTRUM;
据说在使用之前调整矢量大小是一件好事,所以我做了:
SPECTRUM.resize(C1);
for (int i = 0; i < C1; i++)
{
SPECTRUM[i].resize(C2);
}
但是现在我在执行上面的代码(调整大小)
时抛出了运行时异常An unhandled exception of type 'System.Runtime.InteropServices.SEHException' occurred in ConsoleApplication1.exe
在文件xmemory0中。视觉显示此处抛出异常
else if (((size_t)(-1) / sizeof (_Ty) < _Count)
|| (_Ptr = ::operator new(_Count * sizeof (_Ty))) == 0)
_Xbad_alloc(); // report no memory
我还想让你知道,我的计算机上有4 GB RAM可用,我估计我的程序不应该使用超过1 GB的RAM。
答案 0 :(得分:5)
每个oligo
将消耗32个字节。这意味着,如果C1
为“大约100k”,而C2
大于600,则阵列将消耗整整2 GB。
答案 1 :(得分:1)
首先,您确定需要堆中可用的所有内存(ram)吗?
- 你可以在块中进行计算,在其上分配一个块工作并释放它。
- 您可以使用文件存储所有数据,并加载文件块以供计算。
如果你需要很多GB的内存,那么在堆中一次分配所有内存并不好,你永远不会知道剩下的就足够了。
答案 2 :(得分:1)
我怀疑这个问题有一个简单的解决方案,鉴于您正在处理的值,您将需要更多的内存或至少更多的地址空间(这是“可寻址的内存区域”)。最简单的解决方案是使用64位操作系统 - 您可能还需要获得更多RAM,但第一步是允许处理器寻址矩阵中的所有位置 - 并且使用32位,您的限制如果C1为100k,则C2变为600左右。这假设绝对没有其他内存使用 - 不幸的是,这通常不正确。保留前几兆字节以捕获“空指针”,然后代码和堆栈必须存在于某处。最终,100k x 500似乎不太适合,即使总尺寸允许这么多。
另一种选择是使用“稀疏数组”。通常在处理大型矩阵时,在“大多数位置”存在共同的值,并且只有大矩阵中的某些位置具有“不同的值”。在这些情况下,您可以使用检查数据是否存在的方法,如果存在,请使用该值,否则使用默认值。您可以使用例如std::map
作为存储容器,并使用find
方法查看数据是否存在。
答案 3 :(得分:0)
我建议以其他方式解决这个问题。
为数组的每个元素创建一个链接列表(参考数据结构概念)作为Node并将其链接起来。指针足以访问当前节点。
是必须为遍历链表编写机制函数,但有助于在当前目标操作系统中创建如此大的数组,而不是转移到64位。
答案 4 :(得分:-1)
你应该嘲笑这个:
static oligo *spectrum[C1];
for(int i = 0; i < C2; ++i)
{
spectrum[i] = new oligo[C2];
if (spectrum[i] == nullptr)
{
fprintf(stderr, "failed to allocate the array for i=%d.\n", i);
fflush(stderr);
}
}
这将告诉您,您允许分配多少内存以及内存限制是多少。 可能有一些链接器选项来控制此限制...