2017-07-06 55 views
1

我学习一点编程的,我想编写一个蚁群算法QAP,问题是,有时我得到段错误,当我使用的valgrind它告诉我“地址0x0不stack'd,malloc分配或(最近)free'd”。这是代码:C++ Valgrind的:地址0x0不stack'd,malloc分配或(最近)free'd

#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的

无效读:主(antColony.cpp:269) 地址0x0不stack'd,malloc分配或(最近)free'd

过程与信号的默认动作11(SIGSEGV) 访问未映射区域内的地址0x0 在0x804B331终止:主(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] << " "; 
    } 

当我试图打印解向量。

我不明白这个是产生记忆问题。这更令人困惑,因为它有时可以完美运作。如果有人能向我解释,我会很感激。

谢谢期待您的帮助!

+0

检查'''i'''在'''pairSol.second [I]'''是有史以来任一(1)的负或(2)比在阵列'''元件的数量等于或大于second'''。这是什么导致你的错误。 – mgarey

+1

顺便说一句,你知道,当你通过载体的价值,你这样做,他们将被复制每次?你应该用'常量&'而不是路过。 –

+0

您确定要在main()中为外部循环和内部循环使用相同的变量名吗?这可能会导致混淆关于索引到矢量中时使用的'我'。 –

回答

1

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

我看不出这事发生的唯一方法是,如果mejorSolNueva从未分配一个值,但随后分配mejorSol = mejorSolNueva发生。

+0

非常感谢!问题就像你说的那样。我没有初始化mejorSolNueva。在第172行之后,应该有mejorSolNueva = hormigas [0];对于在循环中未分配的罕见情况。 – Cuenta

+0

也感谢关于通过引用传递值的建议,阅读了一些关于该主题的内容,这正是我应该使用的。 – Cuenta

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){ 

mejorSol得到当mejorCostoNuevo大于funCosto的结果时分配。但随后要检查是否mejorCostoNuevo小于mejorCosto。 不应该这两个条件是correspondednce?
更改第二个条件

if (mejorCostoNuevo > mejorCosto){ 

停止生产的错误我。无论如何,如果在for循环的条件是不正确的,它mejorCostoNuevo小于mejorCosto,那么你有大小为零的mejorSol,因此错误。

+0

它在第172行之后丢失了一个分配。它也是一个最小化问题,所以我总是希望少一个。 – Cuenta