我一直试图弄清楚这段时间已经很长一段时间了,通过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 file\n");
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 cities\n");
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 Results\n");
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)我不知道有关发布文件链接的规则,所以希望我不会违反任何规则。
答案 0 :(得分:7)
对于此类错误,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行(在CreateBrute中)分配了一个72字节的块,但是在第150行(在CalcWeight中),你写了8个字节,就在那些72的末尾。
当您注销这样的malloc'd数组的末尾时,它会破坏malloc用于跟踪堆中已分配和释放的内存的信息,结果是后续调用malloc崩溃...