I’ve been trying to figure out this segfault for quite some time now, ran it through GDB and when I type ‘where’ this is what comes up:
#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
Also tried compiling with the params of -Wall -Wextra -O and nothing worth noting came up.
Anyways, here is the code:
#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);
}
The inputs I ran are as follow:
9
8
12
280
37
The program is crashing after the set of numbers for eliteTwo is printed.
EDIT: Forgot to mention, program must be run with a .dat file containing number, i uploaded it here http://www.mediafire.com/download.php?scc4pi71trik48e. (gcc name.c cityweights.dat) I don’t know the rules regarding posting links to files so hopefully I’m not breaking any rules by doing so.
For this kind of error, valgrind is your friend. With your program it immediately tells us:
…plus many more errors.
This specific one is telling us that you allocated a block of 72 bytes at line 97 (in CreateBrute), but then at line 150 (in CalcWeight), you wrote to 8 bytes just past the end of those 72.
When you write off the end of a malloc’d array like this, it corrupts the information that malloc uses to keep track of what memory in the heap has been allocated and freed, with the result that a subsequent call to malloc crashes…