Bas*_*ler 1 c linux 64-bit segmentation-fault calloc
注意:我是学习C的新手,这可能是一个我完全不知道的完全简单的解决方案.在那种情况下,请赐教我.
我在调试C程序时遇到问题,我是从同事处收到的.从本质上讲,我设法将段错误跟踪到失败的调用,calloc()如果n大于46341:
float *v = (float*) calloc(n * (n - 1)/2, sizeof(float));
以下是触发问题的最小代码集:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[]){
int ngenes = 46341;
float *v = (float*) calloc(ngenes * (ngenes - 1)/2, sizeof(float));
if(v) printf("Allocation succeeded\n");
free(v);
ngenes++;
v = (float*) calloc(ngenes * (ngenes - 1)/2, sizeof(float));
if(v) printf("Allocation succeeded\n");
free(v);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在ideone上的代码相同.
AFAIK,这恰好评估为4GiB,这就是我怀疑的原因.我试过的系统都是64位,所以分配不应该是个问题.在SO上搜索已经提出了calloc()可能无法找到连续空间的想法,所以我尝试了多次调用calloc(),并试图调用realloc().最后,我试图实现分配n C++,其中调用会float *v = new float[n * (n - 1)/2]()引发bad_alloc错误.
我一直在尝试这个系统:
$ uname -a Linux picea 3.13.0-35-generic #62-Ubuntu SMP Fri Aug 15 01:58:42 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ free
total used free shared buffers cached
Mem: 396222336 368621612 27600724 32320 281536 346677332
-/+ buffers/cache: 21662744 374559592
Swap: 125061116 64894524 60166592
我试过编译:
gcc -m64 ...
无济于事.运行printf("%lu\n",SIZE_MAX);回报18446744073709551615
老实说,我没有想法.
您最有可能在LP64架构上编译它,其中int32位,但long指针是64位.大小计算最终以整数精度完成,然后提升为64位,从而产生不正确的大小(负数或比预期短得多).
解决方案是使用
size_t ngenes = 46341;
Run Code Online (Sandbox Code Playgroud)
代替.size_t是应该用于内存中对象的大小和长度的类型.