请在我的程序中调用以下函数,以帮助我解决SIGSEGV错误:
int* calculateFitness(int** population, int** townDistancesMatrix, int chromoSize){
int sum = 0;
static int* Fitnesses;
Fitnesses = malloc(sizeof(int)*chromoSize);
for(int i=0; i<chromoSize; i++){
int indexOne = 0;
int indexTwo = 0;
for(int j=0; j<chromoSize-1; j++){
indexOne = population[i][j];
indexTwo = population[i][j+1];
//printf("\n%d %d",indexOne-1,indexTwo-1);
sum += townDistancesMatrix[indexOne-1][indexTwo-1];
}
indexOne = population[i][0];
sum += townDistancesMatrix[indexTwo-1][indexOne-1];
Fitnesses[i] = sum;
sum = 0;
}
return Fitnesses;
}
对于较小的输入(例如5个镇),程序运行没有问题,所以我首先怀疑它是stackoverflow的原因,因为程序始终运行一段时间(直到所有运行的i的值都相似(i=20
),然后停止运行并给出此错误(在GDB中):
程序收到信号SIGSEGV,分段错误。 0x0000000008000b9b在Untitled1.c:97的calculateFitness(人口= 0x7ffffffedcd0,townDistancesMatrix = 0x8403470,chromoSize = 48)中 97 sum + = townDistancesMatrix [indexOne-1] [indexTwo-1];
但是,我在calculateFitness
中没有递归函数调用,因此我认为这可能是由于函数中的局部变量较大,但是局部变量又很小又很小,而且我的数组也是动态创建的,所以不要继续使用堆栈(也许问题出在我的嵌套循环上?)。
我还运行了valgrind(尽管我对它的报告还不太熟悉,我只是用它来获取一些提示),这是报告:
==198== error calling PR_SET_PTRACER, vgdb might block
==198== Use of uninitialised value of size 8
==198== at 0x108B41: calculateFitness (Untitled1.c:92)
==198== by 0x108866: main (Untitled1.c:29)
==198==
==198== Use of uninitialised value of size 8
==198== at 0x108B6E: calculateFitness (Untitled1.c:93)
==198== by 0x108866: main (Untitled1.c:29)
==198==
==198== Invalid read of size 4
==198== at 0x108B9B: calculateFitness (Untitled1.c:97)
==198== by 0x108866: main (Untitled1.c:29)
==198== Address 0x522d43c is 4 bytes before a block of size 192 alloc'd
==198== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==198== by 0x108A56: readDistances (Untitled1.c:74)
==198== by 0x1087EB: main (Untitled1.c:19)
==198==
==198== Invalid read of size 8
==198== at 0x108B87: calculateFitness (Untitled1.c:97)
==198== by 0x108866: main (Untitled1.c:29)
==198== Address 0x522d278 is 8 bytes before a block of size 384 alloc'd
==198== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-
amd64-linux.so)
==198== by 0x108A20: readDistances (Untitled1.c:71)
==198== by 0x1087EB: main (Untitled1.c:19)
==198==
==198==
==198== Process terminating with default action of signal 11 (SIGSEGV)
==198== Access not within mapped region at address 0xFFFFFFFFFC000018
==198== at 0x108B9B: calculateFitness (Untitled1.c:97)
==198== by 0x108866: main (Untitled1.c:29)
==198== If you believe this happened as a result of a stack
==198== overflow in your program's main thread (unlikely but
==198== possible), you can try to increase the size of the
==198== main thread stack using the --main-stacksize= flag.
==198== The main thread stack size used in this run was 8388608.
//...
==198== LEAK SUMMARY:
==198== definitely lost: 0 bytes in 0 blocks
==198== indirectly lost: 0 bytes in 0 blocks
==198== possibly lost: 0 bytes in 0 blocks
==198== still reachable: 13,632 bytes in 70 blocks
==198== suppressed: 0 bytes in 0 blocks
我搜索了该错误的某些部分,例如“仍然可以到达”,这似乎不是我需要注意的地方,但是即使搜索了第一部分,我也不确定。我究竟做错了什么?如果确实是stackoverflow,那么除了递归之外,还有其他导致stackoverflow的原因吗?
答案 0 :(得分:2)
int main(){
int* population[POPSIZE];
和
for(int i=0; i<chromoSize; i++){
int indexOne = 0;
int indexTwo = 0;
for(int j=0; j<chromoSize-1; j++){
indexOne = population[i][j];
indexTwo = population[i][j+1];
您访问的是人口(由 valgrind 表示),您为chromo_size
(初始化上面的 chromoSize )赋予的值48 )中的 POPSIZE 等于20
在 indexOne 和 indexTwo 具有随机值之后,对 townDistancesMatrix 的访问会产生由valgrind发出信号的seg故障
在scanf("%d",&chromo_size);
后的 main 中,检查值为<= POPSIZE 以避免该问题,并增加 POPSIZE 为能够与您的输入文件一起运行
还请注意free(population)
是非法的,因为人口是局部变量,未在堆中分配