关于向量分配的c ++分段错误

时间:2017-07-05 08:28:38

标签: c++ vector segmentation-fault

我正在编写一个用于校正DEM的程序,我经常需要一个像素周围的值,所以我用一个向量来存储它,这里是代码:

vector<float> choixCoordonne (const vector<vector<float>>& tabMnt, int i, int j, int nbLignes, int nbColonnes)
{

    vector <float> alt (9, numeric_limits<float>::infinity());

    if ( i >= 1 && i < nbLignes -1 && j >= 1 && j < nbColonnes-1)
        coord_InCenter(tabMnt, &alt, i, j);


    //Bordure Nord
    else if (i == 0 && j >= 1 && j <nbColonnes-1)
        coord_BordNord(tabMnt, &alt, i, j);
    //Bordure Sud
    else if (i == nbLignes-1 && j >= 1 && j <nbColonnes-1)
        coord_BordSud(tabMnt, &alt, i, j);
    //Bordure Ouest
    else if (j == 0 && i >= 1 && i <nbLignes-1)
        coord_BordOuest(tabMnt, &alt,i, j);
    //Bordure Est
    else if (j == nbColonnes-1 && i >= 1 && i <nbLignes-1)
        coord_BordEst(tabMnt, &alt, i, j);


    // Coin Nord-Ouest
    else if(i == 0 && j==0)
        coord_CoinNO(tabMnt, &alt, i, j);
    // Coin Nord-Est
    else if (i == 0 && j == nbColonnes-1)
        coord_CoinNE(tabMnt, &alt, i, j);
    // Coin Sud-Ouest
    else if (i == nbLignes-1 && j == 0)
        coord_CoinSO(tabMnt, &alt, i, j);
    // Coin Sud-Est
    else if (i == nbLignes-1 && j == nbColonnes -1)
        coord_CoinSE(tabMnt, &alt, i, j);


    else
    {
        cout <<"Erreur au niveau du repérage des cases dans le D8, cases non-classées"<<endl;
    }

    return alt;
}

我的分段错误出现在此函数的fisrt行上。调试器指示stl_vector中的构造函数有问题(特别是函数allocator_traits&gt; :: allocate。我试图使用.resize()而不是构造函数,但我得到了相同的错误。

我在调用此函数的函数下面添加:

void rechercheZoneTraitement(const vector<vector<float>>& DirD8, vector<Position>* zoneTraitement, vector<Position>::iterator itOrigine, const int& nbLignes, const int& nbColonnes)
{
    vector<Position> tempVoisins;
    vector<Position> toTreat;
    vector<Position>::iterator it;

    toTreat.push_back(*itOrigine);
    it = toTreat.begin();

    while (it != toTreat.end())
    {
        cout<<"recherche zone de traitement et longueur d'a traiter : "<<toTreat.size()<<endl;
        cout << "x : "<<it->ligne<<" ; y :"<<it->colonne<<endl;
        tempVoisins = rechercheVoisins(DirD8, *it, nbLignes, nbColonnes);
        for(vector<Position>::iterator itVoisins = tempVoisins.begin(); itVoisins != tempVoisins.end(); ++itVoisins)
        {
            if (find(zoneTraitement->begin(), zoneTraitement->end(), *itVoisins) == zoneTraitement->end())
            {
                toTreat.push_back(*itVoisins);
                zoneTraitement->push_back(*itVoisins);
            }
        }

        toTreat.erase(it);
        it = toTreat.begin();
    }
}


vector<Position> rechercheVoisins (const vector<vector<float>>& DirD8, const Position& origine, const int& nbLignes, const int& nbColonnes)
{
    //vector<float> valeurVoisin;
    vector<Position> posVoisin;
    /*
    cout<<valeurVoisin.size()<<endl;
    valeurVoisin.resize(9);
    cout<<valeurVoisin.size()<<endl;
    */

    vector<float> valeurVoisin = choixCoordonne(DirD8, origine.ligne, origine.colonne, nbLignes, nbColonnes);

    //On commence à +1 car dans valeur voisins il y a aussi la case d'origine
    //et on sait déjà qu'elle est négative !
    //Ici on a pas le soucie des valeurs infinies
    vector<float>::iterator it = find_if (valeurVoisin.begin()+1, valeurVoisin.end(), [](float i){return i<0;});
    while(it != end(valeurVoisin))
    {
        posVoisin.push_back(getPositionWithIndex(distance(valeurVoisin.begin(), it), origine.ligne, origine.colonne));
        it = find_if (next(it), end(valeurVoisin), [](float i){return i<0;});
    }

    return posVoisin;
}

错误出现在while的第二次迭代中(it!= toTreat.end()),我可以打印/访问此迭代的迭代器的值。

我很困惑。

1 个答案:

答案 0 :(得分:0)

 toTreat.push_back(*itVoisins);

在上述语句之后,it已失效,然后在执行

时调用未定义的行为
 toTreat.erase(it);

相反,您可以先删除it,然后再删除push back

 tempVoisins = rechercheVoisins(DirD8, *it, nbLignes, nbColonnes);
 toTreat.erase(it);//You are any how going to do this.Deleting here will save you from invalidating the iterator.
 for(vector<Position>::iterator itVoisins...)
 {}
 .
 .
 //toTreat.erase(it);// You dont need this now.
 it = toTreat.begin();