我已经尝试弄清楚这个segfault已有一段时间了,通过GDB运行它,当我输入'Where'这就是出现的地方:
#0 0x00007ffff7a9bd4a in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff7a9dfb5 in malloc () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00000000004013d1 in CreateGenetic (cityStart=8, cityNum=9, cityWeights=0x7fffffffd270,
Genetic=0x604160) at main.c:175
#3 0x0000000000400cb9 in main (argc=2, argv=0x7fffffffdfd8) at main.c:87
还尝试使用-wall -wextra -o的参数编译,没有值得注意的内容。无论如何,这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
typedef struct BruteForce *BF;
typedef struct GeneticAlgorithm *GA;
int Fact(int);
int CreateBrute(int, int, double[20][20], BF);
int Permutations(int, int, int*, int, double**, double[20][20], BF);
int CalcWeight(int, int, int*, double**, double [20][20], BF);
int CreateGenetic(int, int, double [20][20], GA);
int GeneticWeight(int, int, int *, double **, double [20][20], GA);
int IterativePerm(int, int, int *, int, double **, double [20][20], GA);
struct BruteForce {
double eliteOne[20];
double eliteTwo[20];
int size;
};
struct GeneticAlgorithm {
double elite[20][20];
int size;
int generations;
int runs;
double mutation;
int permutation;
};
int main(int argc, char *argv[]) {
int i = 0, j = 0;
if (argc != 2) {
printf("Missing arguments!n");
exit(1);
}
FILE *data = fopen(argv[1], "r");
if (data == 0) {
printf("Could not open filen");
exit(1);
}
double cityWeights[20][20];
double temp;
/********************************************
*Inputs city weights into 2D array
*******************************************/
while (!feof(data)) {
fscanf(data, "%lf", &temp);
if (i == j && j != 19) {
cityWeights[i][j] = 0;
j++;
} else if (i == j && j >= 19) break;
cityWeights[i][j] = temp;
cityWeights[j][i] = temp;
if (j == 19 && i != 19) {
i++;
j = i;
} else j++;
}
fclose(data);
BF Brute = malloc(sizeof (struct BruteForce));
GA Genetic = malloc(sizeof (struct GeneticAlgorithm));
int cityNum, cityStart;
printf("Number of cities in current run : n");
scanf("%i", &cityNum);
printf("Starting city : n");
scanf("%i", &cityStart);
while (cityStart > cityNum || cityStart <= 0) {
printf("Starting city must be greater than zero and less than number of citiesn");
printf("Starting city : n");
scanf("%i", &cityStart);
}
printf("Number of generations to run : n");
scanf("%i", &Genetic->generations);
printf("Number of individuals in each generation : n");
scanf("%i", &Genetic->runs);
printf("Percentage of each generation to be made with mutations : n");
scanf("%lf", &Genetic->mutation);
Genetic->mutation = (int) ((Genetic->runs * (Genetic->mutation / 100)) + 0.5);
Genetic->permutation = Genetic->runs - Genetic->mutation;
CreateBrute(cityStart, cityNum, cityWeights, Brute);
CreateGenetic(cityStart, cityNum, cityWeights, Genetic);
}
int Fact(int x) {
int i, z = 1;
for (i = 2; i <= x; i++) z *= i;
return z;
}
int CreateBrute(int cityStart, int cityNum, double cityWeights[20][20], BF Brute) {
int i = cityNum - 1;
i = Fact(i);
double** tour;
int x,y;
tour = (double **)malloc(i * sizeof (double*));
for (x = 0; x < i; x++)
tour[x] = (double *) malloc(cityNum * sizeof (double));
for (i = 0; i < cityNum; i++)
tour[0][i] = i;
tour[0][0] = cityStart - 1;
tour[0][cityStart - 1] = 0;
i = cityNum - 1;
i = Fact(i);
int count = 1, *countP;
countP = &count;
Brute->size = cityNum;
Brute->eliteOne[cityNum] = 9999;
Brute->eliteTwo[cityNum] = 9999;
Permutations(i, cityNum, countP, cityNum, tour, cityWeights, Brute);
printf("eliteOne is : n");
for (i = 0; i <= cityNum; i++) printf("%lf ", Brute->eliteOne[i]);
printf("n");
printf("eliteTwo is : n");
for (i = 0; i <= cityNum; i++) printf("%lf ", Brute->eliteTwo[i]);
printf("n");
i = cityNum - 1;
i = Fact(i);
}
int Permutations(int row, int col, int* count, int n, double** tour, double cityWeights[20][20], BF Brute) {
int temp, i, x;
if (n == 1) CalcWeight(row, col, count, tour, cityWeights, Brute);
else {
for (i = 1; i < n; i++) {
temp = tour[0][i];
tour[0][i] = tour[0][n - 1];
tour[0][n - 1] = temp;
Permutations(row, col, count, (n - 1), tour, cityWeights, Brute);
temp = tour[0][i];
tour[0][i] = tour[0][n - 1];
tour[0][n - 1] = temp;
}
}
}
int CalcWeight(int row, int col, int* count, double** tour, double cityWeights[20][20], BF Brute) {
double weight;
int i, xOne, xTwo;
weight = 0;
//Calculates weight of tour
for (i = 0; i < (col - 1); i++) {
xOne = tour[0][i];
xTwo = tour[0][i + 1];
weight += cityWeights[xOne][xTwo];
}
xOne = tour[0][col - 1];
xTwo = tour[0][0];
weight += cityWeights[xOne][xTwo];
tour[0][col] = weight;
if (*count == row) return;
//Stores tours in 2D array
for (i = 0; i <= col; i++) {
tour[*count][i] = tour[0][i];
}
//Finds best routes
if (tour[*count][col] < Brute->eliteOne[col])
for (i = 0; i <= col; i++) Brute->eliteOne[i] = tour[*count][i];
else if (tour[*count][col] < Brute->eliteTwo[col])
for (i = 0; i <= col; i++) Brute->eliteTwo[i] = tour[*count][i];
*count += 1;
}
int CreateGenetic(int cityStart, int cityNum, double cityWeights[20][20], GA Genetic) {
double **tour, **tourMut;
int i, w, x, y, z, a;
tour = (double **) malloc((Genetic->runs + 1) * sizeof (double*));
for (x = 0; x <= Genetic->runs; x++)
tour[x] = (double *) malloc(cityNum * sizeof (double));
for (i = 0; i < cityNum; i++) {
tour[0][i] = i;
}
tourMut = malloc(Genetic->runs * sizeof (double*));
for (x = 0; x < Genetic->runs; x++)
tourMut[x] = malloc(cityNum * sizeof (double));
for (i = 0; i < cityNum; i++) {
tourMut[0][i] = i;
}
tour[0][0] = (cityStart - 1) * 100;
tour[0][cityStart - 1] = 0;
Genetic->size = cityNum;
Genetic->elite[0][cityNum] = 9999;
Genetic->elite[1][cityNum] = 9999;
int countPerm = 1, countMut = 1, *countPP, *countPG;
countPP = &countPerm;
countPG = &countMut;
for (i = 0; i < Genetic->generations; i++) {
for (y = 0; y < Genetic->permutation; y++)
IterativePerm(Genetic->runs, cityNum, countPP, cityNum, tour, cityWeights, Genetic);
for (a=0; a <= cityNum; a++) tourMut[0][a] = Genetic->elite[0][a];
tourMut[0][0] *= 100;
for (z = 0; z < Genetic->mutation; z++){
IterativePerm(Genetic->runs, cityNum, countPG, cityNum, tourMut, cityWeights, Genetic);
}
while(countMut > 1){
for(w=0; w<=cityNum; w++) {
tour[countPerm][w] = tourMut[countMut-1][w];}
countPerm += 1;
countMut -= 1;
}
countPerm = 1;
countMut = 1;
}
fprintf(stderr, "Genetic Resultsn");
fprintf(stderr, "eliteOne is : n");
for (i = 0; i <= cityNum; i++) fprintf(stderr, "%lf ", Genetic->elite[0][i]);
fprintf(stderr, "n");
fprintf(stderr, "eliteTwo is : n");
for (i = 0; i <= cityNum; i++) fprintf(stderr, "%lf ", Genetic->elite[1][i]);
fprintf(stderr, "n");
}
int GeneticWeight(int row, int col, int *count, double **tour, double cityWeights[20][20], GA Genetic) {
tour[0][0] /= 100;
double weight;
int i, xOne, xTwo;
weight = 0;
//Calculates weight of tour
for (i = 0; i < (col - 1); i++) {
xOne = tour[0][i];
xTwo = tour[0][i + 1];
weight += cityWeights[xOne][xTwo];
}
xOne = tour[0][col - 1];
xTwo = tour[0][0];
weight += cityWeights[xOne][xTwo];
tour[0][col] = weight;
if (*count == row) return;
//Stores tours in 2D array
for (i = 0; i <= col; i++) {
tour[*count][i] = tour[0][i];
}
//Finds best routes
if (tour[*count][col] < Genetic->elite[0][col])
for (i = 0; i <= col; i++) Genetic->elite[0][i] = tour[*count][i];
else if (tour[*count][col] < Genetic->elite[1][col])
for (i = 0; i <= col; i++) Genetic->elite[1][i] = tour[*count][i];
*count += 1;
tour[0][0] *= 100;
}
int IterativePerm(int row, int col, int *count, int n, double **s, double cityWeights[20][20], GA Genetic) {
int nf = n, i, m, k, p, q;
nf = Fact(nf);
double temp;
for (i = 1; i < nf; i++) {
m = n - 2;
while (s[0][m] > s[0][m + 1]) m--;
k = n - 1;
while (m < 0)m++;
while (s[0][m] > s[0][k]) k--;
temp = s[0][m];
s[0][m] = s[0][k];
s[0][k] = temp;
p = m + 1;
q = n - 1;
while (p < q) {
temp = s[0][p];
s[0][p] = s[0][q];
s[0][q] = temp;
p++;
q--;
}
}
GeneticWeight(row, col, count, s, cityWeights, Genetic);
}
我运行的输入如下:
9
8
12
280
37
打印了Elitetwo的数字集后,该程序正在崩溃。
编辑:忘了提及,必须使用包含数字的.dat文件运行程序,我在此处上传http://www.mediafire.com/download.php?scc4pi71trik48e。(gcc name.c cityweights.dat)我不知道有关发布到文件的链接的规则,因此希望我不会这样做。
对于这种错误,valgrind是您的朋友。通过您的程序,它立即告诉我们:
==23699== Memcheck, a memory error detector
==23699== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==23699== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==23699== Command: ./tso5 cityweights.dat
==23699== Parent PID: 14008
==23699==
==23699== Invalid write of size 8
==23699== at 0x400978: CalcWeight (tso5.c:150)
==23699== by 0x400C96: Permutations (tso5.c:129)
==23699== by 0x400C96: Permutations (tso5.c:129)
==23699== by 0x400C96: Permutations (tso5.c:129)
==23699== by 0x400C96: Permutations (tso5.c:129)
==23699== by 0x400C96: Permutations (tso5.c:129)
==23699== by 0x400C96: Permutations (tso5.c:129)
==23699== by 0x400C96: Permutations (tso5.c:129)
==23699== by 0x400C96: Permutations (tso5.c:129)
==23699== by 0x4010C5: CreateBrute (tso5.c:109)
==23699== by 0x402188: main (tso5.c:80)
==23699== Address 0x5213db8 is 0 bytes after a block of size 72 alloc'd
==23699== at 0x4C28FAC: malloc (vg_replace_malloc.c:236)
==23699== by 0x400E4A: CreateBrute (tso5.c:97)
==23699== by 0x402188: main (tso5.c:80)
...加上更多错误。
这个特定的是告诉我们,您在第97行(在Create Brute中)分配了一个72个字节的块,但随后在第150行(计算重量)中,您写信给8个字节,就在这72的末尾。p>当您注销像这样的malloc'd数组的末端时,它会破坏Malloc用来跟踪堆已分配和释放的内存的信息,结果是随后对Malloc崩溃的调用...