向量分配上的c ++分段错误

Posted

技术标签:

【中文标题】向量分配上的c ++分段错误【英文标题】:c++ segmentation fault on an allocation of vector 【发布时间】:2017-07-05 08:28:37 【问题描述】:

我正在编写一个用于校正 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;

我的分段错误出现在此函数的第一行。调试器指示 stl_vector 中的构造函数有问题(特别是函数 allocator_traits>::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()),我可以打印/访问此迭代的迭代器的值。

我很困惑。

【问题讨论】:

你在toTreat上做了一些push_back,所以你使it无效,然后你试图删除它,这是未定义的行为。 你试过写mcve 谢谢大家,这是问题所在...... 【参考方案1】:
 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();

【讨论】:

以上是关于向量分配上的c ++分段错误的主要内容,如果未能解决你的问题,请参考以下文章

C ++中动态分配的向量中的分段错误

c++向量分配错误分段错误

为啥 C++ 标准向量在分配或调整大小时会出现段错误? [关闭]

使用 MATLAB mex 将向量与另一个向量分配时出现分段错误

向量分割错误向量

loop-malloc.c 的向量中的分段错误:没有这样的文件或目录