2

我正在设置一个非常大的数组来处理原始神经元模拟。为数组分配内存(大约 8-9 Gig)时,New[] 会出错。我能够获得 C 风格的 malloc 来保留内存,但是一旦我尝试分配一个值,我就会得到一个访问冲突读取位置 0xffffffffffffffff。

我正在运行带有 Visual Studio 2010 Professional 的 64 位 Windows 7。我也尝试过使用嵌套循环的 malloc 和 new[] ,它们也崩溃了。

如果 malloc 不可能做到这一点,我还应该考虑什么?我需要能够非常快速地访问大内存空间的东西。谢谢您的考虑。

#include "stdafx.h"
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <iomanip>
#include <locale>
#include <math.h>
using namespace std;

int nRows;
int nCols;
int nDepth;
int nData;

int main()
{
        //unsigned long int brainSize=100;
        //nRows = int(pow(brainSize,0.3333333333333333333333333333))+1;
            nRows=80;
        nCols=nRows; 
        nDepth=nRows;
        nData=2000;

        double brainData = nRows*nCols*nDepth*nData;
        double brainBits = 4*brainData;
        cout.imbue(std::locale(""));
        cout << fixed << "Brain size : " << nRows*nCols*nDepth << " neurons \nBrain integers : " << setprecision(0) << brainData << "\nBrain bits: " << brainBits << endl;

    __int64 ****brain;
    brain =  (__int64 ****)malloc(nRows*nCols*nDepth*nData*sizeof(__int64 ****));
        cout << "Brain initialized.";
        brain [2][2][2][2]=2; // error is here. 
        cout << brain[2][2][2][2];


    int breaker;
    cin >> breaker; //pause
    return 0;

}
4

2 回答 2

2

有几点需要考虑:

  • 您确定要创建 64 位可执行文件吗?只是在运行
  • 有多少可用内存(包括物理内存和交换内存)
  • 你传递给什么类型malloc?确保你使用size_t而不是int
  • 也许VirtualAlloc会起作用(尽管这会将您的程序限制在 Windows 上)

您可能要考虑改用内存映射文件。您无需自己分配所有内存,而是分配它,但它由文件支持。然后,操作系统会担心确保当您访问它时(您将其视为常规new/ malloc'd 内存)它可供您使用。如果有足够的物理 RAM 可用,它可能会将整个内容保存在内存中,否则它将根据需要将位分页。

一般来说,内存映射文件会更好地工作,因为它应该始终有效,即使在内存较少的系统上也是如此。并且它将允许更高的内存使用率。当然,您可能可以构建自己的缓存方案(将一些内容保存在内存中,将其他内容保存在磁盘上),但操作系统设计人员非常擅长这些事情,因此这可能不是您的主要目标(构建缓存系统)你不妨让操作系统完成它的工作。

于 2012-04-19T02:28:16.330 回答
1

问题是您要声明一个指向指向 64 位整数指针的指针的指针,而不是 64 位整数的四维数组。当您使用 链取消引用它时[2][2][2][2],编译器会在您刚刚分配的未初始化块中查找指针,尝试取消引用它,然后立即崩溃。

如果四个大小中的至少三个(例如nRowsnColumnsnDepth)是编译时常量,则可以分配nData3-D 数组,并使用常规方括号语法来访问元素。如果这是不可能的,您要么不得不忍受指针的开销,要么分配一个“普通”数组并在其中实现自己的寻址方案以使其相信它是 4-D。

PS我在这里默默地假设使用的开销vector<...>在你的情况下是禁止的。但是,如果您有足够的内存用于附加指针,我肯定会选择 64 位整数向量的向量:它速度快、可靠且易于使用。

编辑:如果四个维度中的三个是常量,您可以这样做:

#include <iostream>

const int nRows = 11;
const int nColumns = 13;
const int nDepth = 17;

typedef long long brain_block[nRows][nColumns][nDepth];

int main() {
    int nData = 123;
    brain_block *brain = (brain_block*)malloc(nData*sizeof(brain_block));
    memset(brain, 0, nData*sizeof(brain_block));
    brain[2][2][2][2] = 2;
    std::cout << brain[2][2][2][2] << std::endl;
    free(brain);
}
于 2012-04-19T02:38:12.913 回答