Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 调试错误的分配错误c++;_C++_Memory - Fatal编程技术网

C++ 调试错误的分配错误c++;

C++ 调试错误的分配错误c++;,c++,memory,C++,Memory,当我运行代码时,一切似乎都正常工作,但经过一定的时间步数(通常为~100,但每次的次数不同)后,我得到错误: “在抛出'std::bad_alloc'实例后终止调用” 我真的不知道如何调试它,因为它不会在每次代码运行的同一点上发生。我将发布我的代码,但它相当长,而且承认有点混乱(这是我第一次真正尝试用c++编写程序),但我将尝试解释它的结构,以及我认为最可能出现错误的地方 基本结构是我有一个“birds”(我定义的一个类)数组,它通过一些相当复杂的计算选择如何在每一步更新自己。在这样做的过程中,

当我运行代码时,一切似乎都正常工作,但经过一定的时间步数(通常为~100,但每次的次数不同)后,我得到错误:

“在抛出'std::bad_alloc'实例后终止调用”

我真的不知道如何调试它,因为它不会在每次代码运行的同一点上发生。我将发布我的代码,但它相当长,而且承认有点混乱(这是我第一次真正尝试用c++编写程序),但我将尝试解释它的结构,以及我认为最可能出现错误的地方

基本结构是我有一个“birds”(我定义的一个类)数组,它通过一些相当复杂的计算选择如何在每一步更新自己。在这样做的过程中,它定期调用函数getVisualState来更新一个链接列表,每个鸟都将该列表存储为其“视觉状态”。我相信这是我在模拟过程中唯一一次动态分配内存,所以我想这很有可能是错误的根源。函数Bird::resetVisualState()应该在分配的内存被使用后将其清除(但看起来我并没有耗尽内存,至少在任务管理器中监视它)

如果有人能看到任何他们认为可能是问题根源的东西,那就太棒了,或者如果不只是关于我应该如何调试这个问题的任何建议

#include <iostream>
#include <cmath>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <ctime>
#include <vector>
#include <algorithm>
#include <fstream>

#include "birdClasses.h"

using namespace std;

/*
nBirds, nSteps, nF, v, dt, birdRad defined in "birdClasses.h"
*/

//define other parameters.
const int nSensors = 20;
const int nMoves = 3; //no. possible moves at each step.
double dTheta = 15*M_PI/180.0; //angle that birds can change their orientation by in a timestep.
double moves[nMoves] = {-dTheta, 0, dTheta}; //possible moves.
double noise = 0.0;
double initBoxX = 20, initBoxY = 20; //size of initial box particles are placed in.
double sensorFrac[nSensors];
double sensorRef[nSensors];
double sensorRange = 2*M_PI/((double)nSensors);
int counter = 0;

int nps = numStates(nMoves,nF);
int *possibleStates = new int[nps];


//variables to record positions and orientations.
double xPositions[nSteps][nBirds], yPositions[nSteps][nBirds], orientations[nSteps][nBirds];

//array to keep track of which collisions are possible.
int couldCollide[nF][nBirds][nBirds];

//function prototypes
bool checkCollision(int i, int nFut, Bird *birds, double xi, double yi);
unsigned long int getVisualState(Bird *birdList, int nFut, int i, double cX, double cY, double cAng);
void updateTree(double exploreX, double exploreY, double exploreO, Bird *bird, int bn, int nFut);

int main()
{
    sensorRef[0] = sensorRange;
    for(int u=1; u<nSensors; u++) sensorRef[u] = sensorRef[u-1] + sensorRange;

    //set up GSL random number generator.
    const gsl_rng_type * Tr;
    gsl_rng * RNG;
    gsl_rng_env_setup();
    Tr = gsl_rng_default;
    RNG = gsl_rng_alloc (Tr);
    gsl_rng_set(RNG,time(NULL));

    //set up output
    ofstream output("output.txt");

    //initialize birds in a box randomly, all with the same orientation.
    Bird birdList[nBirds];

    for(int i=0; i<nBirds; i++) {
        birdList[i].set_position(gsl_ran_flat(RNG,0,initBoxX),gsl_ran_flat(RNG,0,initBoxY));
    }


    //ACTUAL CODE

    int uniqueVisStates[nMoves];
    double cX, cY, fX, fY, exploreX, exploreY, exploreO;


    //main time step loop
    for(int ts=0; ts<nSteps; ts++) {

        //save current positions
        for(int i=0; i<nBirds; i++) {
            xPositions[ts][i] = birdList[i].get_xPos();
            yPositions[ts][i] = birdList[i].get_yPos();
            orientations[ts][i] = birdList[i].get_orientation();
            birdList[i].updateFuture();
        }

        //update list of possible collisions.
        for(int nFut=0; nFut<nF; nFut++) {
            for(int i=0; i<nBirds; i++) {
                cX = birdList[i].get_xPos(); cY = birdList[i].get_yPos();
                counter = 0;
                for(int j=0; j<nBirds; j++) {
                    if(i==j) {
                        continue;
                    } else {
                        fX = birdList[j].get_futureX(nFut); fY = birdList[j].get_futureY(nFut);
                        if((cX-fX)*(cX-fX)+(cY-fY)*(cY-fY) < ((nFut+1)*v*dt+2*birdRad)*((nFut+1)*v*dt+2*birdRad)) {
                                couldCollide[nFut][i][counter]=j;
                                counter++;
                        }
                    }
                }
                if(counter < nBirds) couldCollide[nFut][i][counter]=-1;
            }
        }

        //loop over birds to choose how they update their orientation.
        for(int bn=0; bn<nBirds; bn++) {
            //loop over possible moves bird can make NOW.

            for(int l=0; l<nMoves; l++) {
                uniqueVisStates[l]=0;
            }

            for(int mn=0; mn<nMoves; mn++) {
                for(int l=0; l<nps; l++) {
                    possibleStates[l]=0;
                }
                counter = 0;
                exploreO = birdList[bn].get_orientation() + moves[mn];
                exploreX = birdList[bn].get_xPos() + cos(exploreO)*v*dt;
                exploreY = birdList[bn].get_yPos() + sin(exploreO)*v*dt;
                updateTree(exploreX,exploreY,exploreO,&birdList[0],bn,0);
                vector<int> visStates (possibleStates,possibleStates+counter);
                vector<int>::iterator it;
                sort (visStates.begin(),visStates.end());
                it = unique(visStates.begin(),visStates.end());
                uniqueVisStates[mn] = distance(visStates.begin(),it);

            }
            int maxInd = 0, maxVal = uniqueVisStates[0];
            for(int h=1; h<nMoves; h++) {
                if(uniqueVisStates[h] > maxVal) {
                    maxInd = h; maxVal = uniqueVisStates[h];
                } else if(uniqueVisStates[h]==maxVal) {
                    if(abs(moves[h])<abs(moves[maxInd])) {
                        maxInd = h;
                    }
                }
            }
            birdList[bn].update_Orientation(moves[maxInd]);
            birdList[bn].update_Pos(birdList[bn].get_xPos()+cos(birdList[bn].get_orientation())*v*dt,birdList[bn].get_yPos()+sin(birdList[bn].get_orientation())*v*dt);
        }

        for(int bn=0; bn<nBirds; bn++) birdList[bn].finishUpdate();
        cout << ts << "\n";
    }

    //OUTPUT DATA INTO A TEXT FILE.
    for(int ts=0; ts<(nSteps-1); ts++) {
        for(int bn=0; bn<nBirds; bn++) {
            output << xPositions[ts][bn] << " " << yPositions[ts][bn] << " " << orientations[ts][bn] << "\n";
        }
    }

    delete[] possibleStates;


    return 0;
}

bool checkCollision(int i, int nFut, Bird *birds, double xi, double yi) {
    int cond = 1; int index, counti=0;
    while(cond) {
        index = couldCollide[nFut][i][counti];
        if(index==-1) break;
        double xj = birds[index].get_futureX(nFut);
        double yj = birds[index].get_futureY(nFut);
        if((xi-xj)*(xi-xj)+(yi-yj)*(yi-yj) < 4*birdRad*birdRad) {
            return 1;
        }
        counti++;
        if(counti==nBirds) break;
    }
    return 0;
}

unsigned long int getVisualState(Bird *birdList, int nFut, int i, double cX, double cY, double cAng) {
    //finds the visual state of bird i based on its current "exploring position" and the predicted positions of other birds at timestep nFut.
    //visual state is defined by discretizing the bird's field of view into nSensors (relative to current orientation) and creating a vector of
    //0s and 1s depending on whether each sensor is < half covered or not. This is then converted to an integer (as we are actually interested only
    //in the number of unique visual states.
    double relX, relY, relDist, dAng, s, dTheta, ang1, ang2;
    //clear current visual state.
    birdList[i].resetVisualState();

    for(int j=0; j<nBirds; j++) {
        if(i==j) continue;
        relX = birdList[j].get_futureX(nFut)-cX;
        relY = birdList[j].get_futureY(nFut)-cY;
        relDist = sqrt(relX*relX+relY*relY);
        dAng = acos((cos(cAng)*relX+sin(cAng)*relY)/relDist);
        dTheta = atan(birdRad/relDist);
        s = cos(cAng)*relY - sin(cAng)*relX;
        if( s<0 ) dAng = 2*M_PI-dAng;
        ang1 = dAng - dTheta; ang2 = dAng + dTheta;
        if( ang1 < 0 ) {
            birdList[i].addInterval(0,ang2);
            birdList[i].addInterval(2*M_PI+ang1,2*M_PI);
        } else if( ang2 > 2*M_PI ) {
            birdList[i].addInterval(0,fmod(ang2,2*M_PI));
            birdList[i].addInterval(ang1,2*M_PI);
        } else {
            birdList[i].addInterval(ang1,ang2);
        }
    }
    Node *sI = birdList[i].get_visualState();
    birdList[i].cleanUp(sI);
    int ind1, ind2;
    for(int k=0; k<nSensors; k++) sensorFrac[k]=0.0; //initialize.
    while(sI->next->next != 0) {
        ang1 = sI->value; ang2 = sI->next->value;
        ind1 = floor(ang1/sensorRange); ind2 = floor(ang2/sensorRange);
        if(ind2==nSensors) ind2--; //this happens if ang2 = 2pi (which can happen a lot).
        if(ind1==ind2) {
            sensorFrac[ind1] += (ang2-ang1)/sensorRange;
        } else if(ind2-ind1==1) {
            sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
            sensorFrac[ind2] += (ang2-sensorRef[ind1])/sensorRange;
        } else {
            sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
            sensorFrac[ind2] += (ang2-sensorRef[ind2-1])/sensorRange;
            for(int y=ind1+1;y<ind2;y++) sensorFrac[y] = 1.0;
        }
        sI=sI->next->next;
    }
    //do final interval separately.
    ang1 = sI->value; ang2 = sI->next->value;
    ind1 = floor(ang1/sensorRange); ind2 = floor(ang2/sensorRange);
    if(ind2==nSensors) ind2--; //this happens if ang2 = 2pi (which can happen a lot).
    if(ind1==ind2) {
        sensorFrac[ind1] += (ang2-ang1)/sensorRange;
    } else if(ind2-ind1==1) {
        sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
        sensorFrac[ind2] += (ang2-sensorRef[ind1])/sensorRange;
    } else {
        sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
        sensorFrac[ind2] += (ang2-sensorRef[ind2-1])/sensorRange;
        for(int y=ind1+1;y<ind2;y++) sensorFrac[y] = 1.0;
    }
    int output = 0, multiplier = 1;
    for(int y=0; y<nSensors; y++) {
        if(sensorFrac[y]>0.5) output += multiplier;
        multiplier *= 2;
    }

    return output;
}

void updateTree(double exploreX, double exploreY, double exploreO, Bird *bird, int bn, int nFut) {
    double o,x,y;
    if(checkCollision(bn,nFut,bird,exploreX,exploreY)) return;
    int vs = getVisualState(bird,nFut,bn,exploreX,exploreY,exploreO);
    possibleStates[counter] = vs;
    counter++;
    if(nFut < (nF-1)) {
        for(int m=0; m<nMoves; m++) {
            o = exploreO + moves[m];
            x = exploreX + cos(o)*v*dt;
            y = exploreY + sin(o)*v*dt;
            updateTree(x,y,o,bird,bn,nFut+1);
        }
    } else {
        return;
    }
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“birdClasses.h”
使用名称空间std;
/*
“BirdClass.h”中定义的NBIRD、NSTEP、nF、v、dt、birdRad
*/
//定义其他参数。
传感器常数=20;
常数int nMoves=3//不,每一步都有可能移动。
双dTheta=15*M_PI/180.0//鸟类可以在一个时间步长内改变方向的角度。
双动[nMoves]={-dTheta,0,dTheta}//可能的行动。
双噪声=0.0;
双initBoxX=20,initBoxY=20//放置的初始长方体粒子的大小。
双传感器FRAC[N传感器];
双传感器参考[N传感器];
双传感器量程=2*M_PI/((双)N传感器);
int计数器=0;
int nps=numStates(nMoves,nF);
int*possiblestate=新的int[nps];
//用于记录位置和方向的变量。
双X位置[nSteps][nBirds]、Y位置[nSteps][nBirds]、方向[nSteps][nBirds];
//数组以跟踪哪些碰撞是可能的。
int可以碰撞[nF][nBirds][nBirds];
//功能原型
席考碰撞(INTI,INT NFUT,鸟*鸟,双喜,双义);
无符号长整型整型getVisualState(Bird*birdList、整型nFut、整型i、双cX、双cY、双cAng);
void updateTree(双exploreX、双exploreY、双exploreO、Bird*Bird、int bn、int nFut);
int main()
{
sensorRef[0]=传感器范围;
对于(int u=1;u
或者,如果不是关于我应该如何调试它的任何建议

#include <iostream>
#include <cmath>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <ctime>
#include <vector>
#include <algorithm>
#include <fstream>

#include "birdClasses.h"

using namespace std;

/*
nBirds, nSteps, nF, v, dt, birdRad defined in "birdClasses.h"
*/

//define other parameters.
const int nSensors = 20;
const int nMoves = 3; //no. possible moves at each step.
double dTheta = 15*M_PI/180.0; //angle that birds can change their orientation by in a timestep.
double moves[nMoves] = {-dTheta, 0, dTheta}; //possible moves.
double noise = 0.0;
double initBoxX = 20, initBoxY = 20; //size of initial box particles are placed in.
double sensorFrac[nSensors];
double sensorRef[nSensors];
double sensorRange = 2*M_PI/((double)nSensors);
int counter = 0;

int nps = numStates(nMoves,nF);
int *possibleStates = new int[nps];


//variables to record positions and orientations.
double xPositions[nSteps][nBirds], yPositions[nSteps][nBirds], orientations[nSteps][nBirds];

//array to keep track of which collisions are possible.
int couldCollide[nF][nBirds][nBirds];

//function prototypes
bool checkCollision(int i, int nFut, Bird *birds, double xi, double yi);
unsigned long int getVisualState(Bird *birdList, int nFut, int i, double cX, double cY, double cAng);
void updateTree(double exploreX, double exploreY, double exploreO, Bird *bird, int bn, int nFut);

int main()
{
    sensorRef[0] = sensorRange;
    for(int u=1; u<nSensors; u++) sensorRef[u] = sensorRef[u-1] + sensorRange;

    //set up GSL random number generator.
    const gsl_rng_type * Tr;
    gsl_rng * RNG;
    gsl_rng_env_setup();
    Tr = gsl_rng_default;
    RNG = gsl_rng_alloc (Tr);
    gsl_rng_set(RNG,time(NULL));

    //set up output
    ofstream output("output.txt");

    //initialize birds in a box randomly, all with the same orientation.
    Bird birdList[nBirds];

    for(int i=0; i<nBirds; i++) {
        birdList[i].set_position(gsl_ran_flat(RNG,0,initBoxX),gsl_ran_flat(RNG,0,initBoxY));
    }


    //ACTUAL CODE

    int uniqueVisStates[nMoves];
    double cX, cY, fX, fY, exploreX, exploreY, exploreO;


    //main time step loop
    for(int ts=0; ts<nSteps; ts++) {

        //save current positions
        for(int i=0; i<nBirds; i++) {
            xPositions[ts][i] = birdList[i].get_xPos();
            yPositions[ts][i] = birdList[i].get_yPos();
            orientations[ts][i] = birdList[i].get_orientation();
            birdList[i].updateFuture();
        }

        //update list of possible collisions.
        for(int nFut=0; nFut<nF; nFut++) {
            for(int i=0; i<nBirds; i++) {
                cX = birdList[i].get_xPos(); cY = birdList[i].get_yPos();
                counter = 0;
                for(int j=0; j<nBirds; j++) {
                    if(i==j) {
                        continue;
                    } else {
                        fX = birdList[j].get_futureX(nFut); fY = birdList[j].get_futureY(nFut);
                        if((cX-fX)*(cX-fX)+(cY-fY)*(cY-fY) < ((nFut+1)*v*dt+2*birdRad)*((nFut+1)*v*dt+2*birdRad)) {
                                couldCollide[nFut][i][counter]=j;
                                counter++;
                        }
                    }
                }
                if(counter < nBirds) couldCollide[nFut][i][counter]=-1;
            }
        }

        //loop over birds to choose how they update their orientation.
        for(int bn=0; bn<nBirds; bn++) {
            //loop over possible moves bird can make NOW.

            for(int l=0; l<nMoves; l++) {
                uniqueVisStates[l]=0;
            }

            for(int mn=0; mn<nMoves; mn++) {
                for(int l=0; l<nps; l++) {
                    possibleStates[l]=0;
                }
                counter = 0;
                exploreO = birdList[bn].get_orientation() + moves[mn];
                exploreX = birdList[bn].get_xPos() + cos(exploreO)*v*dt;
                exploreY = birdList[bn].get_yPos() + sin(exploreO)*v*dt;
                updateTree(exploreX,exploreY,exploreO,&birdList[0],bn,0);
                vector<int> visStates (possibleStates,possibleStates+counter);
                vector<int>::iterator it;
                sort (visStates.begin(),visStates.end());
                it = unique(visStates.begin(),visStates.end());
                uniqueVisStates[mn] = distance(visStates.begin(),it);

            }
            int maxInd = 0, maxVal = uniqueVisStates[0];
            for(int h=1; h<nMoves; h++) {
                if(uniqueVisStates[h] > maxVal) {
                    maxInd = h; maxVal = uniqueVisStates[h];
                } else if(uniqueVisStates[h]==maxVal) {
                    if(abs(moves[h])<abs(moves[maxInd])) {
                        maxInd = h;
                    }
                }
            }
            birdList[bn].update_Orientation(moves[maxInd]);
            birdList[bn].update_Pos(birdList[bn].get_xPos()+cos(birdList[bn].get_orientation())*v*dt,birdList[bn].get_yPos()+sin(birdList[bn].get_orientation())*v*dt);
        }

        for(int bn=0; bn<nBirds; bn++) birdList[bn].finishUpdate();
        cout << ts << "\n";
    }

    //OUTPUT DATA INTO A TEXT FILE.
    for(int ts=0; ts<(nSteps-1); ts++) {
        for(int bn=0; bn<nBirds; bn++) {
            output << xPositions[ts][bn] << " " << yPositions[ts][bn] << " " << orientations[ts][bn] << "\n";
        }
    }

    delete[] possibleStates;


    return 0;
}

bool checkCollision(int i, int nFut, Bird *birds, double xi, double yi) {
    int cond = 1; int index, counti=0;
    while(cond) {
        index = couldCollide[nFut][i][counti];
        if(index==-1) break;
        double xj = birds[index].get_futureX(nFut);
        double yj = birds[index].get_futureY(nFut);
        if((xi-xj)*(xi-xj)+(yi-yj)*(yi-yj) < 4*birdRad*birdRad) {
            return 1;
        }
        counti++;
        if(counti==nBirds) break;
    }
    return 0;
}

unsigned long int getVisualState(Bird *birdList, int nFut, int i, double cX, double cY, double cAng) {
    //finds the visual state of bird i based on its current "exploring position" and the predicted positions of other birds at timestep nFut.
    //visual state is defined by discretizing the bird's field of view into nSensors (relative to current orientation) and creating a vector of
    //0s and 1s depending on whether each sensor is < half covered or not. This is then converted to an integer (as we are actually interested only
    //in the number of unique visual states.
    double relX, relY, relDist, dAng, s, dTheta, ang1, ang2;
    //clear current visual state.
    birdList[i].resetVisualState();

    for(int j=0; j<nBirds; j++) {
        if(i==j) continue;
        relX = birdList[j].get_futureX(nFut)-cX;
        relY = birdList[j].get_futureY(nFut)-cY;
        relDist = sqrt(relX*relX+relY*relY);
        dAng = acos((cos(cAng)*relX+sin(cAng)*relY)/relDist);
        dTheta = atan(birdRad/relDist);
        s = cos(cAng)*relY - sin(cAng)*relX;
        if( s<0 ) dAng = 2*M_PI-dAng;
        ang1 = dAng - dTheta; ang2 = dAng + dTheta;
        if( ang1 < 0 ) {
            birdList[i].addInterval(0,ang2);
            birdList[i].addInterval(2*M_PI+ang1,2*M_PI);
        } else if( ang2 > 2*M_PI ) {
            birdList[i].addInterval(0,fmod(ang2,2*M_PI));
            birdList[i].addInterval(ang1,2*M_PI);
        } else {
            birdList[i].addInterval(ang1,ang2);
        }
    }
    Node *sI = birdList[i].get_visualState();
    birdList[i].cleanUp(sI);
    int ind1, ind2;
    for(int k=0; k<nSensors; k++) sensorFrac[k]=0.0; //initialize.
    while(sI->next->next != 0) {
        ang1 = sI->value; ang2 = sI->next->value;
        ind1 = floor(ang1/sensorRange); ind2 = floor(ang2/sensorRange);
        if(ind2==nSensors) ind2--; //this happens if ang2 = 2pi (which can happen a lot).
        if(ind1==ind2) {
            sensorFrac[ind1] += (ang2-ang1)/sensorRange;
        } else if(ind2-ind1==1) {
            sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
            sensorFrac[ind2] += (ang2-sensorRef[ind1])/sensorRange;
        } else {
            sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
            sensorFrac[ind2] += (ang2-sensorRef[ind2-1])/sensorRange;
            for(int y=ind1+1;y<ind2;y++) sensorFrac[y] = 1.0;
        }
        sI=sI->next->next;
    }
    //do final interval separately.
    ang1 = sI->value; ang2 = sI->next->value;
    ind1 = floor(ang1/sensorRange); ind2 = floor(ang2/sensorRange);
    if(ind2==nSensors) ind2--; //this happens if ang2 = 2pi (which can happen a lot).
    if(ind1==ind2) {
        sensorFrac[ind1] += (ang2-ang1)/sensorRange;
    } else if(ind2-ind1==1) {
        sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
        sensorFrac[ind2] += (ang2-sensorRef[ind1])/sensorRange;
    } else {
        sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
        sensorFrac[ind2] += (ang2-sensorRef[ind2-1])/sensorRange;
        for(int y=ind1+1;y<ind2;y++) sensorFrac[y] = 1.0;
    }
    int output = 0, multiplier = 1;
    for(int y=0; y<nSensors; y++) {
        if(sensorFrac[y]>0.5) output += multiplier;
        multiplier *= 2;
    }

    return output;
}

void updateTree(double exploreX, double exploreY, double exploreO, Bird *bird, int bn, int nFut) {
    double o,x,y;
    if(checkCollision(bn,nFut,bird,exploreX,exploreY)) return;
    int vs = getVisualState(bird,nFut,bn,exploreX,exploreY,exploreO);
    possibleStates[counter] = vs;
    counter++;
    if(nFut < (nF-1)) {
        for(int m=0; m<nMoves; m++) {
            o = exploreO + moves[m];
            x = exploreX + cos(o)*v*dt;
            y = exploreY + sin(o)*v*dt;
            updateTree(x,y,o,bird,bn,nFut+1);
        }
    } else {
        return;
    }
}
您可以尝试在gdb中设置catchpoint以捕获
std::bad_alloc
异常:

(gdb) catch throw bad_alloc
(见附件)

如果您能够在gdb中复制此错误分配,那么您可以查看
bt
以查看此异常的可能原因

或者,如果不是关于我应该如何调试它的任何建议

#include <iostream>
#include <cmath>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <ctime>
#include <vector>
#include <algorithm>
#include <fstream>

#include "birdClasses.h"

using namespace std;

/*
nBirds, nSteps, nF, v, dt, birdRad defined in "birdClasses.h"
*/

//define other parameters.
const int nSensors = 20;
const int nMoves = 3; //no. possible moves at each step.
double dTheta = 15*M_PI/180.0; //angle that birds can change their orientation by in a timestep.
double moves[nMoves] = {-dTheta, 0, dTheta}; //possible moves.
double noise = 0.0;
double initBoxX = 20, initBoxY = 20; //size of initial box particles are placed in.
double sensorFrac[nSensors];
double sensorRef[nSensors];
double sensorRange = 2*M_PI/((double)nSensors);
int counter = 0;

int nps = numStates(nMoves,nF);
int *possibleStates = new int[nps];


//variables to record positions and orientations.
double xPositions[nSteps][nBirds], yPositions[nSteps][nBirds], orientations[nSteps][nBirds];

//array to keep track of which collisions are possible.
int couldCollide[nF][nBirds][nBirds];

//function prototypes
bool checkCollision(int i, int nFut, Bird *birds, double xi, double yi);
unsigned long int getVisualState(Bird *birdList, int nFut, int i, double cX, double cY, double cAng);
void updateTree(double exploreX, double exploreY, double exploreO, Bird *bird, int bn, int nFut);

int main()
{
    sensorRef[0] = sensorRange;
    for(int u=1; u<nSensors; u++) sensorRef[u] = sensorRef[u-1] + sensorRange;

    //set up GSL random number generator.
    const gsl_rng_type * Tr;
    gsl_rng * RNG;
    gsl_rng_env_setup();
    Tr = gsl_rng_default;
    RNG = gsl_rng_alloc (Tr);
    gsl_rng_set(RNG,time(NULL));

    //set up output
    ofstream output("output.txt");

    //initialize birds in a box randomly, all with the same orientation.
    Bird birdList[nBirds];

    for(int i=0; i<nBirds; i++) {
        birdList[i].set_position(gsl_ran_flat(RNG,0,initBoxX),gsl_ran_flat(RNG,0,initBoxY));
    }


    //ACTUAL CODE

    int uniqueVisStates[nMoves];
    double cX, cY, fX, fY, exploreX, exploreY, exploreO;


    //main time step loop
    for(int ts=0; ts<nSteps; ts++) {

        //save current positions
        for(int i=0; i<nBirds; i++) {
            xPositions[ts][i] = birdList[i].get_xPos();
            yPositions[ts][i] = birdList[i].get_yPos();
            orientations[ts][i] = birdList[i].get_orientation();
            birdList[i].updateFuture();
        }

        //update list of possible collisions.
        for(int nFut=0; nFut<nF; nFut++) {
            for(int i=0; i<nBirds; i++) {
                cX = birdList[i].get_xPos(); cY = birdList[i].get_yPos();
                counter = 0;
                for(int j=0; j<nBirds; j++) {
                    if(i==j) {
                        continue;
                    } else {
                        fX = birdList[j].get_futureX(nFut); fY = birdList[j].get_futureY(nFut);
                        if((cX-fX)*(cX-fX)+(cY-fY)*(cY-fY) < ((nFut+1)*v*dt+2*birdRad)*((nFut+1)*v*dt+2*birdRad)) {
                                couldCollide[nFut][i][counter]=j;
                                counter++;
                        }
                    }
                }
                if(counter < nBirds) couldCollide[nFut][i][counter]=-1;
            }
        }

        //loop over birds to choose how they update their orientation.
        for(int bn=0; bn<nBirds; bn++) {
            //loop over possible moves bird can make NOW.

            for(int l=0; l<nMoves; l++) {
                uniqueVisStates[l]=0;
            }

            for(int mn=0; mn<nMoves; mn++) {
                for(int l=0; l<nps; l++) {
                    possibleStates[l]=0;
                }
                counter = 0;
                exploreO = birdList[bn].get_orientation() + moves[mn];
                exploreX = birdList[bn].get_xPos() + cos(exploreO)*v*dt;
                exploreY = birdList[bn].get_yPos() + sin(exploreO)*v*dt;
                updateTree(exploreX,exploreY,exploreO,&birdList[0],bn,0);
                vector<int> visStates (possibleStates,possibleStates+counter);
                vector<int>::iterator it;
                sort (visStates.begin(),visStates.end());
                it = unique(visStates.begin(),visStates.end());
                uniqueVisStates[mn] = distance(visStates.begin(),it);

            }
            int maxInd = 0, maxVal = uniqueVisStates[0];
            for(int h=1; h<nMoves; h++) {
                if(uniqueVisStates[h] > maxVal) {
                    maxInd = h; maxVal = uniqueVisStates[h];
                } else if(uniqueVisStates[h]==maxVal) {
                    if(abs(moves[h])<abs(moves[maxInd])) {
                        maxInd = h;
                    }
                }
            }
            birdList[bn].update_Orientation(moves[maxInd]);
            birdList[bn].update_Pos(birdList[bn].get_xPos()+cos(birdList[bn].get_orientation())*v*dt,birdList[bn].get_yPos()+sin(birdList[bn].get_orientation())*v*dt);
        }

        for(int bn=0; bn<nBirds; bn++) birdList[bn].finishUpdate();
        cout << ts << "\n";
    }

    //OUTPUT DATA INTO A TEXT FILE.
    for(int ts=0; ts<(nSteps-1); ts++) {
        for(int bn=0; bn<nBirds; bn++) {
            output << xPositions[ts][bn] << " " << yPositions[ts][bn] << " " << orientations[ts][bn] << "\n";
        }
    }

    delete[] possibleStates;


    return 0;
}

bool checkCollision(int i, int nFut, Bird *birds, double xi, double yi) {
    int cond = 1; int index, counti=0;
    while(cond) {
        index = couldCollide[nFut][i][counti];
        if(index==-1) break;
        double xj = birds[index].get_futureX(nFut);
        double yj = birds[index].get_futureY(nFut);
        if((xi-xj)*(xi-xj)+(yi-yj)*(yi-yj) < 4*birdRad*birdRad) {
            return 1;
        }
        counti++;
        if(counti==nBirds) break;
    }
    return 0;
}

unsigned long int getVisualState(Bird *birdList, int nFut, int i, double cX, double cY, double cAng) {
    //finds the visual state of bird i based on its current "exploring position" and the predicted positions of other birds at timestep nFut.
    //visual state is defined by discretizing the bird's field of view into nSensors (relative to current orientation) and creating a vector of
    //0s and 1s depending on whether each sensor is < half covered or not. This is then converted to an integer (as we are actually interested only
    //in the number of unique visual states.
    double relX, relY, relDist, dAng, s, dTheta, ang1, ang2;
    //clear current visual state.
    birdList[i].resetVisualState();

    for(int j=0; j<nBirds; j++) {
        if(i==j) continue;
        relX = birdList[j].get_futureX(nFut)-cX;
        relY = birdList[j].get_futureY(nFut)-cY;
        relDist = sqrt(relX*relX+relY*relY);
        dAng = acos((cos(cAng)*relX+sin(cAng)*relY)/relDist);
        dTheta = atan(birdRad/relDist);
        s = cos(cAng)*relY - sin(cAng)*relX;
        if( s<0 ) dAng = 2*M_PI-dAng;
        ang1 = dAng - dTheta; ang2 = dAng + dTheta;
        if( ang1 < 0 ) {
            birdList[i].addInterval(0,ang2);
            birdList[i].addInterval(2*M_PI+ang1,2*M_PI);
        } else if( ang2 > 2*M_PI ) {
            birdList[i].addInterval(0,fmod(ang2,2*M_PI));
            birdList[i].addInterval(ang1,2*M_PI);
        } else {
            birdList[i].addInterval(ang1,ang2);
        }
    }
    Node *sI = birdList[i].get_visualState();
    birdList[i].cleanUp(sI);
    int ind1, ind2;
    for(int k=0; k<nSensors; k++) sensorFrac[k]=0.0; //initialize.
    while(sI->next->next != 0) {
        ang1 = sI->value; ang2 = sI->next->value;
        ind1 = floor(ang1/sensorRange); ind2 = floor(ang2/sensorRange);
        if(ind2==nSensors) ind2--; //this happens if ang2 = 2pi (which can happen a lot).
        if(ind1==ind2) {
            sensorFrac[ind1] += (ang2-ang1)/sensorRange;
        } else if(ind2-ind1==1) {
            sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
            sensorFrac[ind2] += (ang2-sensorRef[ind1])/sensorRange;
        } else {
            sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
            sensorFrac[ind2] += (ang2-sensorRef[ind2-1])/sensorRange;
            for(int y=ind1+1;y<ind2;y++) sensorFrac[y] = 1.0;
        }
        sI=sI->next->next;
    }
    //do final interval separately.
    ang1 = sI->value; ang2 = sI->next->value;
    ind1 = floor(ang1/sensorRange); ind2 = floor(ang2/sensorRange);
    if(ind2==nSensors) ind2--; //this happens if ang2 = 2pi (which can happen a lot).
    if(ind1==ind2) {
        sensorFrac[ind1] += (ang2-ang1)/sensorRange;
    } else if(ind2-ind1==1) {
        sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
        sensorFrac[ind2] += (ang2-sensorRef[ind1])/sensorRange;
    } else {
        sensorFrac[ind1] += (sensorRef[ind1]-ang1)/sensorRange;
        sensorFrac[ind2] += (ang2-sensorRef[ind2-1])/sensorRange;
        for(int y=ind1+1;y<ind2;y++) sensorFrac[y] = 1.0;
    }
    int output = 0, multiplier = 1;
    for(int y=0; y<nSensors; y++) {
        if(sensorFrac[y]>0.5) output += multiplier;
        multiplier *= 2;
    }

    return output;
}

void updateTree(double exploreX, double exploreY, double exploreO, Bird *bird, int bn, int nFut) {
    double o,x,y;
    if(checkCollision(bn,nFut,bird,exploreX,exploreY)) return;
    int vs = getVisualState(bird,nFut,bn,exploreX,exploreY,exploreO);
    possibleStates[counter] = vs;
    counter++;
    if(nFut < (nF-1)) {
        for(int m=0; m<nMoves; m++) {
            o = exploreO + moves[m];
            x = exploreX + cos(o)*v*dt;
            y = exploreY + sin(o)*v*dt;
            updateTree(x,y,o,bird,bn,nFut+1);
        }
    } else {
        return;
    }
}
您可以尝试在gdb中设置catchpoint以捕获
std::bad_alloc
异常:

(gdb) catch throw bad_alloc
(见附件)


如果您能够在gdb中复制这个错误的配置,那么您可以查看
bt
,查看此异常的可能原因。

我认为这是一个逻辑错误,不一定与内存有关

在void addInterval(双l,双r)中,您声明

Node *curr_L = visualState;
Node *prev_L = visualState;
这些指针现在将指向成员visualState指向的任何对象

稍后,您将更改visualState以指向新创建的节点

Node *newRoot = new Node;
// ....
if(curr_L == visualState) {
  visualState = newRoot;
但是您的指针curr\u L和prev\u L仍将指向visualState以前指向的任何对象。更改这些指针的唯一时间是在

if(curr_L->next->next != 0) {
  prev_L = curr_L;
  curr_L = curr_L->next->next;
这和

if(WHATEVER_VISUAL_STATE_USED_TO_POINT_TO->next->next != 0) {
  prev_L = curr_L;
  curr_L = curr_L->next->next;
这是您的意图吗?您可以通过在编辑器中查找*curr\u L=*来遵循curr\u L的赋值

我建议在一个小数据样本上测试您的代码,并确保您的代码符合您的意图。使用调试器或跟踪输出。使用

如果您有权访问它,我想您会喜欢valgrind。

我认为这是一个逻辑错误,不一定与内存有关

在void addInterval(双l,双r)中,您声明

Node *curr_L = visualState;
Node *prev_L = visualState;
这些指针现在将指向成员visualState指向的任何对象

稍后,您将更改visualState以指向新创建的节点

Node *newRoot = new Node;
// ....
if(curr_L == visualState) {
  visualState = newRoot;
但是您的指针curr\u L和prev\u L仍将指向visualState以前指向的任何对象。更改这些指针的唯一时间是在

if(curr_L->next->next != 0) {
  prev_L = curr_L;
  curr_L = curr_L->next->next;
这和

if(WHATEVER_VISUAL_STATE_USED_TO_POINT_TO->next->next != 0) {
  prev_L = curr_L;
  curr_L = curr_L->next->next;
这是您的意图吗?您可以通过在编辑器中查找*curr\u L=*来遵循curr\u L的赋值

我建议在一个小数据样本上测试您的代码,并确保您的代码符合您的意图。使用调试器或跟踪输出。使用

如果你能访问它,我想你会很感激valgrind。

如果你停止删除东西,错误会消失吗?@NeilGatenby那肯定会让问题变得更糟。
std::bad_alloc
是指当你尝试
新建
时,没有足够的堆内存可供分配。故意泄漏内存无助于此p问题。如果你没有删除代码,那么情况会变得更糟,如果答案是“是”,那么它有助于追踪原因你为
可能的属性分配了多少元素
?你创建了多少
节点
对象?你
新建了多少内容
(或
新建[]
)?你
删除了多少内容
(或
delete[]
)完成后删除所有内容?您是否想过一种更动态的算法,不需要立即将所有内容保存在内存中?您在玩一个危险的游戏。Bird的析构函数不会删除视觉状态,而我