[英]Can malloc be relied on to return contiguous memory, and how do I properly call it?
在我开始之前,是的,我已经阅读了可能的重复 , malloc在linux中很奇怪 , 在malloc上的cplusplus.com并在谷歌上做了一些搜索。
我有一个科学计算问题,需要一个非常大的2D阵列。 我正在关注“C中的数字配方”的副本中找到的代码,并且在我的2D数组中间遇到了未分配内存的问题。 我在Windows中工作,并使用c ++与MSVC 2012。
这是我的2D数组分配
unsigned long nrl=0;
unsigned long nrh=749774;
unsigned long ncl=0
unsigned long nch=250657;
unsigned long i, nrow=nrh-nrl+1,ncol=nch-ncl+1;
double **m;
if((size_t)(nrow*ncol)<(size_t)nrow){
m=NULL;
return m;
}
/*allocate pointers to rows*/
m=(double **)malloc((size_t)(nrow)*sizeof(double*));
if (!m){
m=NULL;
return m;
}
/*allocate rows and set pointers to them*/
m[nrl]=(double *) malloc((size_t)((nrow*ncol)*sizeof(double)));
if(!m[nrl]){
free(m[nrl]);
free(m);
m=NULL;
return m;
}
for(i=nrl+1;i<=nrh;i++)m[i]=m[i-1]+ncol;
/*The 2D array should now be callable as m[nrow][ncol]*/
/*Pseudo-code below*/
m[0][0] == Good, allocated memory
m[125][200923] == Unallocated, crashes program
m[nrh-1][nch-1] == Good, allocated memory
我目前依赖malloc在内存分配失败时返回NULL(如果我尝试分配非常大的数组,我实际上会得到NULL值。
另外,我尝试了double *m = new double[nch*nrh]
,但这给了我一个内存分配错误。 我对替代实现的任何建议持开放态度,但我需要能够知道分配是否有效并在必要时重新分配较小的块。
编辑:
这是交流功能,但我的大部分代码都是用c ++编写的。
更新:
感谢大卫,我能够解决问题。 更改我的溢出检查
if((size_t)(nrow*ncol)<(size_t)nrow)
至
if(SIZE_MAX/nrow < ncol || SIZE_MAX/ncol < nrow || nrow*ncol<nrow)
允许malloc在应该的时候失败。
我猜你有32位进程。 请注意, nrow*ncol*sizeof(double)
是(很多!)大于2 ^ 32。 您实际上正在尝试分配1400 GB,我认为这对您来说是一个惊喜。
它很可能无法分配那么多内存,当然也不是32位进程。 您的代码似乎运行,因为(nrow*ncol)*sizeof(double)
遭受整数溢出,因此您对malloc
的调用成功但不会分配您期望它的内存。 事实上,即使是在64位的过程中,你有溢出,因为nrow*ncol
与32位的算术评估,因为你宣布nrow
和ncol
是unsigned long
。 它们应该是size_t
。
无论如何,您将需要重新考虑您的问题的整个方法。 你真的希望用1400 GB的密集矩阵做任何有用的事情吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.