0

我一直试图找出这个段错误已经有一段时间了,通过 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) 我不知道关于发布文件链接的规则,所以希望我这样做不会违反任何规则。

4

1 回答 1

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 数组的末尾时,它会破坏 malloc 用来跟踪堆中已分配和释放的内存的信息,结果是随后对 malloc 的调用崩溃......

于 2012-10-22T06:17:14.170 回答