c ++ Valgrind:地址0x0没有堆叠,malloc'd或(最近)free'd

时间:2017-07-06 20:00:32

标签: c++ valgrind

我正在学习一些编程,我正在尝试为QAP编写一个Ant Colony算法,问题是我有时会遇到分段错误,当我使用valgrind它告诉我“地址0x0没有堆栈,malloc '或(最近)自由“。这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>  //ifstream
#include <string>
#include <sstream>
#include <vector>
#include <utility> //pair
#include <iostream>
#include <algorithm> //shuffle
#include <random> //default_random_engine
#include <chrono> //chrono::system_clock
#include <cstdlib> // rand
#include <unistd.h>
#include <csignal>
using namespace std;

sig_atomic_t volatile done = 0;
void game_over(int) { done = 1; }

int funCosto(int dim,vector<int> sol,vector<int> dist, vector<int> flujo){
    int costo = 0;
    for (int i = 0; i<dim;i++){
        for (int j = i+1; j<dim;j++){
            // El costo es la * del valor de los flujos por la permutacion de las distancias 
            costo += flujo[dim*i+j] * dist[dim*(sol[i]-1) + (sol[j]-1)]; 
        }
    }
    return costo*2; //La matriz es simétrica
}

int buscarLista(vector<int> lista, int elemento, int dim){
    int aux = 0;
    for (int i = 0; i < dim; i++){
        if (lista[i] == elemento){aux = 1;}
    }
    return aux;
}

vector<int> localSearch(int dim,vector<int> sol, vector<int> dist, vector<int> flujo){

    vector<int> solActual(dim), solAux(dim);
    solActual = sol;
    int mejorCosto = funCosto(dim,solActual,dist,flujo);
    int costoActual, mejorCostoAnterior;

    do{
        mejorCostoAnterior = mejorCosto; // para determinar que se llegó a un óptimo local
        for (int i = 0; i < dim; i++){
            for (int j = i+1; j < dim; j++){
                solAux = solActual;
                solAux[i] = solActual[j];
                solAux[j] = solActual[i]; //intercambiamos dos elementos
                /*Importante, hay que optimizar el cálculo del costo de los vecinos*/
                costoActual = funCosto(dim,solAux,dist,flujo);
                if (costoActual<mejorCosto){
                    break;
                }
            }
            if (costoActual < mejorCosto){
                mejorCosto = costoActual; //se actualiza el mejor costo
                solActual = solAux; //se efectua el movimiento
                break; 
            }
        }
    } while (mejorCosto < mejorCostoAnterior); //se detiene cuando ya no hay mejoría

    return solActual;
}

pair<int,vector<int>> antColony(int numAnts, int dim, vector<int> dist, vector<int> flujo){

    done = 0;
    std::signal(SIGALRM, game_over);
    alarm(300);

    vector<vector<int>> hormigas(numAnts, vector<int>(dim));
    vector<vector<int>> hormigasNuevas(numAnts, vector<int>(dim));
    vector<vector<double>> feromonas(dim, vector<double>(dim));
    vector<int> mejorSol, mejorSolNueva;
    double mejorCosto, mejorCostoNuevo, totalFer, prob, auxProb, probAcum = 0 ;
    int numSwaps = dim/3;  // número de cambios que va a hacer cada hormiga en cada iteración
    random_device rd; // obtener un número aleatorio de hardware
    mt19937 eng(rd()); // semilla para el generador
    uniform_int_distribution<> disInt(0,dim-1);
    uniform_real_distribution<> disReal(0,1);
    int prim, seg, aux, contadorRep, sinMejoria = 0; //indices 
    int inten = 1; //la intensificación está prendida al comienzo

    for (int i = 1; i <= dim; i++){
        hormigas[0][i-1] = i;
    }
    for (int j = 1; j < numAnts; j++){
        hormigas[j] = hormigas[0];
    }
    //obtener una semilla basada en el tiempo
    for (int k = 0; k < numAnts; k++){
        unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
        shuffle(hormigas[k].begin(),hormigas[k].end(), default_random_engine(seed));
    } 

    for (int i = 0; i < numAnts; i++){ //aplica local Search para las soluciones aleatorias
        hormigas[i] = localSearch(dim,hormigas[i],dist,flujo);
    }

    mejorCosto = funCosto(dim,hormigas[0],dist,flujo);
    mejorSol = hormigas[0];
    for (int i = 1; i < numAnts; i++){
        if (funCosto(dim,hormigas[i],dist,flujo) < mejorCosto){
            mejorCosto = funCosto(dim,hormigas[i],dist,flujo);
            mejorSol = hormigas[i];
        }
    }
    for (int i = 0; i<dim; i++){
        for (int j = 0 ; j<dim; j++){
            feromonas[i][j] = 1.0/(100*mejorCosto);
        }
    }

    for (int z = 0; z < 1; z++){ //máximo número de iteraciones

        for (int i = 0; i < numAnts; i++ ){

            hormigasNuevas[i] = hormigas[i];

            for (int j = 0; j < numSwaps; j++){
                prim = disInt(eng);
                auxProb = disReal(eng);
                seg = -1;
                probAcum = 0;
                do{
                    seg++;
                    if (seg == prim){seg++;}
                    totalFer = 0; //limpiamos para esta iteración
                    for (int k = 0; k < dim; k++){
                        if (k != prim){
                            totalFer += feromonas[prim][hormigasNuevas[i][k]-1] + feromonas[k][hormigasNuevas[i][prim]-1];
                        }
                    }    
                    //construimos la probabilidad con la que es aceptado el cambio segun las feromonas
                    prob = (feromonas[prim][hormigasNuevas[i][seg]-1]+feromonas[seg][hormigasNuevas[i][prim]-1]) / totalFer;
                    probAcum += prob;
                }while ((auxProb > probAcum) && (seg < dim));

                if (seg == dim){seg--;}

                aux = hormigasNuevas[i][prim];
                hormigasNuevas[i][prim] = hormigasNuevas[i][seg];
                hormigasNuevas[i][seg] = aux;

            }
            //mejoramos la solución modificada por la hormiga
            hormigasNuevas[i] = localSearch(dim,hormigasNuevas[i],dist,flujo);
        }

        //contadorRep = 0;
        //intensificación
        for (int a = 0; a < numAnts; a++){
            if (inten == 1){
                if (funCosto(dim,hormigasNuevas[a],dist,flujo) < funCosto(dim,hormigas[a],dist,flujo)){
                    hormigas[a] = hormigasNuevas[a];
                }
                else{ contadorRep++;} //para contar cuantas veces se queda con la respuesta anterior
            }
            else{
                hormigas[a] = hormigasNuevas[a];
            }
        }

        //if (contadorRep == numAnts){inten = 0;} //apaga la intensificación

        mejorCostoNuevo = funCosto(dim,hormigas[0],dist,flujo);
        for (int b = 1; b < numAnts; b++){
            if (funCosto(dim,hormigas[b],dist,flujo) < mejorCostoNuevo){
                mejorCostoNuevo = funCosto(dim,hormigas[b],dist,flujo);
                mejorSolNueva = hormigas[b];
            }
        }

        if (mejorCostoNuevo < mejorCosto){
            //si se consigue una mejor solucíón
            mejorCosto = mejorCostoNuevo;
            mejorSol = mejorSolNueva;
            inten = 1;
            sinMejoria = 0;
        }

        //actualiación de la matriz de feromonas
        for (int c = 0; c < dim; c++){
            for (int d = 0; d < dim; d++){ //Evaporación
                feromonas[c][d] = 0.9*feromonas[c][d];
            }
        }

        for (int e = 0; e < dim; e++){//reforzamos la mejor solución
            feromonas[e][mejorSol[e]-1] = feromonas[e][mejorSol[e]-1] + 0.1/mejorCosto;
        }

        //diversificación
        if (sinMejoria > dim/2){

            hormigas[0] = mejorSol; //se queda la mejor solución hasta el momento
            //se vuelve a inicializar las hormigas
            for (int k = 1; k < numAnts; k++){
                unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
                shuffle(hormigas[k].begin(),hormigas[k].end(), default_random_engine(seed));
            } 

            for (int i = 0; i < numAnts; i++){ //aplica local Search para las soluciones aleatorias
                hormigas[i] = localSearch(dim,hormigas[i],dist,flujo);
            }

            mejorCosto = funCosto(dim,hormigas[0],dist,flujo);
            mejorSol = hormigas[0];
            for (int i = 1; i < numAnts; i++){
                if (funCosto(dim,hormigas[i],dist,flujo) < mejorCosto){
                    mejorCosto = funCosto(dim,hormigas[i],dist,flujo);
                    mejorSol = hormigas[i];
                }
            }

            //renovar la matriz de feromonas
            for (int i = 0; i<dim; i++){
                for (int j = 0 ; j<dim; j++){
                    feromonas[i][j] = 1.0/(100*mejorCosto);
                }
            }
        }
        sinMejoria++;
    }

    pair <int,vector<int>> pairSol = make_pair (mejorCosto,mejorSol);
    return pairSol; 

}

int main (int argc, char* argv[]) {

    vector<int> resultados(10);
    for (int i = 0; i < 10; i++){

        clock_t startTime = clock();
        ifstream file(argv[1]);
        int dim;  //dimensiones de las matrices
        file >> dim;
        vector<int> suc(dim*dim); //matriz con los flujos entre las sucursales
        vector<int> loc(dim*dim); //matriz con las distancias de las localidades
        pair <int,vector<int>> pairSol; //tiene el costo de la busqueda y la permutación

        //guardar la matriz de distancia
        for (int i = 0; i < dim; i++){ 
            for (int j = 0; j < dim; j++) {
                file >> suc[dim*i+j];
            }
        }

        //guardar la matriz de flujos
        for (int i = 0; i < dim; i++){ 
            for (int j = 0; j < dim; j++) {
                file >> loc[dim*i+j];
            }
        }

        pairSol = antColony(10,dim,loc,suc);
        resultados[i] = pairSol.first;
        cout << pairSol.first << endl;

        for (int i = 0; i < dim; i++){
            cout << pairSol.second[i] << " ";
        }
        cout << endl;

        cout << double( clock() - startTime ) / (double)CLOCKS_PER_SEC<< " seconds." << endl;
    }

    int total = 0;
    for (int j = 0; j<10; j++){
        total += resultados[j];
    }

    cout << endl << "El promedio de de las soluciones es: " <<endl;
    cout << total/10 << endl;

    return 0;
} 

Valgrind给了我这个:

0x804B331处无效读取大小4:main(antColony.cpp:269) 地址0x0未堆叠,malloc'd或(最近)自由

使用信号11(SIGSEGV)的默认操作终止进程 不在地址0x0的映射区域内访问 在0x804B331:main(antColony.cpp:269)

我正在使用此文件:

20

 0 87 14  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
87  0  0 82 57  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
14  0  0  0  0 68  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 0 82  0  0  0  0 19 18 38 47  0  0  0  0  0  0  0  0  0  0
 0 57  0  0  0  0  0  0  0  0 91  0  0  0  0  0  0  0  0  0
 0  0 68  0  0  0  0  0  0  0  0 77  0  0  0  0  0  0  0  0
 0  0  0 19  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 0  0  0 18  0  0  0  0  0  0  0  0  6  0  0  0  0  0  0  0
 0  0  0 38  0  0  0  0  0  0  0  0  0 75  0  0  0  0  0  0
 0  0  0 47  0  0  0  0  0  0  0  0  0  0 73 52  0  0  0  0
 0  0  0  0 91  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0 77  0  0  0  0  0  0  0  0  0  0 51  0  0  0
 0  0  0  0  0  0  0  6  0  0  0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0 75  0  0  0  0  0  0  0  0 93  0  0
 0  0  0  0  0  0  0  0  0 73  0  0  0  0  0  0  0  0 84  0
 0  0  0  0  0  0  0  0  0 52  0  0  0  0  0  0  0  0  0 40
 0  0  0  0  0  0  0  0  0  0  0 51  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0  0  0  0 93  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0  0  0  0  0 84  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0  0  0  0  0  0 40  0  0  0  0

0 4 7 7 4 6 3 7 1 7 8 7 2 9 8 2 9 3 4 3
4 0 8 1 7 9 8 7 6 5 1 3 1 4 4 2 7 6 3 5
7 8 0 5 7 9 1 6 3 2 9 8 4 8 7 7 4 3 7 1
7 1 5 0 3 1 9 9 7 1 6 6 1 1 2 2 4 2 7 8
4 7 7 3 0 9 9 6 9 4 1 8 2 9 8 6 1 9 2 6
6 9 9 1 9 0 7 6 9 2 3 1 4 1 9 5 3 3 7 3
3 8 1 9 9 7 0 3 7 3 5 1 9 4 6 4 7 4 9 6
7 7 6 9 6 6 3 0 7 1 6 7 3 9 4 1 8 4 9 1
1 6 3 7 9 9 7 7 0 6 1 5 7 6 5 3 4 9 8 1
7 5 2 1 4 2 3 1 6 0 6 3 9 3 3 6 4 1 8 6
8 1 9 6 1 3 5 6 1 6 0 6 3 8 2 4 8 1 9 6
7 3 8 6 8 1 1 7 5 3 6 0 8 2 7 6 4 5 4 1
2 1 4 1 2 4 9 3 7 9 3 8 0 4 4 2 5 6 4 9
9 4 8 1 9 1 4 9 6 3 8 2 4 0 3 2 8 7 2 8
8 4 7 2 8 9 6 4 5 3 2 7 4 3 0 4 3 3 8 4
2 2 7 2 6 5 4 1 3 6 4 6 2 2 4 0 8 5 9 9
9 7 4 4 1 3 7 8 4 4 8 4 5 8 3 8 0 1 2 7
3 6 3 2 9 3 4 4 9 1 1 5 6 7 3 5 1 0 1 1
4 3 7 7 2 7 9 9 8 8 9 4 4 2 8 9 2 1 0 4
3 5 1 8 6 3 6 1 1 6 6 1 9 8 4 9 7 1 4 0

错误来自接近结尾的这一行:

    for (int i = 0; i < dim; i++){
        cout << pairSol.second[i] << " ";
    }

我正在尝试打印解决方案向量。

我不明白这会产生的内存问题。这更令人困惑,因为有时它完美无缺。如果有人能向我解释,我将不胜感激。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

我稍微调试了你的程序,发现当错误发生时,pairSol.second实际上是空的。

我发现这种情况的唯一方法是,mejorSolNueva永远不会分配值,但会发生分配mejorSol = mejorSolNueva

答案 1 :(得分:0)

在这部分代码中看起来像问题:

mejorCostoNuevo = funCosto(dim,hormigas[0],dist,flujo);
for (int b = 1; b < numAnts; b++){
    if (funCosto(dim,hormigas[b],dist,flujo) < mejorCostoNuevo){
        mejorCostoNuevo = funCosto(dim,hormigas[b],dist,flujo);
        mejorSolNueva = hormigas[b];
    }
}

if (mejorCostoNuevo < mejorCosto){
    //si se consigue una mejor solucíón
    mejorCosto = mejorCostoNuevo;
    mejorSol = mejorSolNueva;
    inten = 1;
    sinMejoria = 0;
}

在循环中你有条件

    if (funCosto(dim,hormigas[b],dist,flujo) < mejorCostoNuevo){

接下来你有了

if (mejorCostoNuevo < mejorCosto){
当mejorCostoNuevo大于funCosto的结果时,会指定mejorSol。但是你要检查mejorCostoNuevo是否小于mejorCosto。 这两个条件不应该相应吗? 将第二个条件更改为

if (mejorCostoNuevo > mejorCosto){

停止为我制造错误。无论如何,如果for循环中的条件不为真并且mejorCostoNuevo小于mejorCosto,那么你有mejorSol的零大小,从而错误。