首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有巨大多维数组的malloc,在神经科学sim上失败了

具有巨大多维数组的malloc,在神经科学sim上失败了
EN

Stack Overflow用户
提问于 2012-04-19 02:24:49
回答 2查看 762关注 0票数 2

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

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

如果malloc不可能这样做,我还应该考虑什么呢?我需要能快速访问大内存空间的东西。谢谢你的考虑。

代码语言:javascript
复制
#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;

}
EN

回答 2

Stack Overflow用户

发布于 2012-04-19 02:28:16

有几件事要考虑:

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

您可能需要考虑使用内存映射文件来代替。不是自己分配所有内存,而是分配内存,但它是由文件支持的。然后,操作系统会担心,当您访问它(就像它是常规的new/malloc'd内存一样)时,它对您是可用的。如果有足够的物理内存可用,它可能会将整个内存保存在内存中,否则它将按需要分页位。

通常,内存映射文件会更好地工作,因为这应该总是有效的,即使在内存较少的系统中也是如此。而且它将允许更高的内存使用量。当然,您可能会构建自己的缓存方案(在内存中保留一些东西,在磁盘上保留一些东西),但是操作系统设计人员非常擅长这些东西,所以因为这可能不是您的主要目标(构建一个缓存系统),所以最好让操作系统完成它的工作。

票数 2
EN

Stack Overflow用户

发布于 2012-04-19 02:38:12

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

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

我在这里默默地假设,在您的情况下,使用vector<...>的开销是很高的。但是,如果您有足够的内存来处理额外的指针,我肯定会选择64位整数的向量:它速度快,可靠,而且易于使用。

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

代码语言:javascript
复制
#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);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10220826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档