一个简单的程序编译正常,但会产生运行时错误:segmentation fault: 11
int length=10000;
int num=100;
int num1=20;
int datablocklen=400002; //datablocklen=2*num1*length+2
int main(){
double arr[num*length];
double res[num][num];
for(int i=0;i<num;i++){
for(int j=0;j<num;j++){
res[i][j]=0;
}
}
for(int i=0;i<(num*length);i++){
arr[i]=i;
}
int ntile=(int)(num/num1);
double array_task[datablocklen];
for(int i=0;i<ntile;i++){
for(int j=0;j<ntile;j++){
array_task[datablocklen-2]=i*num1*length;
array_task[datablocklen-1]=j*num1*length;
for(int k=0;k<(num1*length);k++){
array_task[k]=arr[i*num1*length+k];
array_task[num1*length+k]=arr[j*num1*length];
}
}
}
return 0;
}
gcc -o test -std=c99 test.c
获取可执行文件。
奇怪的是,如果长度被赋予一个较小的值,例如1000,则不会显示错误。但是当它大于10000时,会发生分段错误。
请注意我始终密切关注datablocklen的值,以确保datablocklen=2*num1*length+2
。因此,如果length
或num1
发生变化,我也会更改变量datablocklen
。
我在mac,OS yosemite下处理gdb时仍有问题。所以我没有用gdb调试程序。但是如果我注释内部for循环,循环由k索引,程序执行正常。我的意思是,没有错误信息。
答案 0 :(得分:3)
我认为堆栈内存在这里是个问题。
两种解决方案:
要么增加进程的堆栈大小。
通常ulimit -s
将显示linux中任何进程的默认大小,mac
而不是在堆栈double arr[num*length];
中使用malloc
进行大型数组分配,以便在堆中进行此类内存分配。
答案 1 :(得分:0)
你可能正在堆满了。它的默认值通常约为8MB。由于您的分配大小是固定的,因此您可以将大数组移动到全局空间并将许多固定值切换为定义。这是一个例子[请原谅无偿的风格清理]:
#define LENGTH 10000
#define NUM 100
#define NUM1 20
#define NTILE (NUM / NUM1)
#if 0
#define DATABLOCKLEN 400002 // DATABLOCKLEN=2*NUM1*LENGTH+2
#else
#define DATABLOCKLEN (2 * NUM1 * LENGTH + 2)
#endif
double arr[NUM * LENGTH];
double res[NUM][NUM];
double array_task[DATABLOCKLEN];
int
main()
{
for (int i = 0; i < NUM; i++) {
for (int j = 0; j < NUM; j++) {
res[i][j] = 0;
}
}
for (int i = 0; i < (NUM * LENGTH); i++) {
arr[i] = i;
}
for (int i = 0; i < NTILE; i++) {
for (int j = 0; j < NTILE; j++) {
array_task[DATABLOCKLEN - 2] = i * NUM1 * LENGTH;
array_task[DATABLOCKLEN - 1] = j * NUM1 * LENGTH;
for (int k = 0; k < (NUM1 * LENGTH); k++) {
array_task[k] = arr[i * NUM1 * LENGTH + k];
array_task[NUM1 * LENGTH + k] = arr[j * NUM1 * LENGTH];
}
}
}
return 0;
}