尝试访问类内部的布尔值时的Segfault

时间:2014-02-08 00:09:29

标签: c++ segmentation-fault

const int PIXEL_WIDTH = 10;
const int PIXEL_HEIGHT = 10;
const int WORLD_X = 64; //WORLD_X * PIXEL WIDTH = SCREEN_WIDTH if you want the world to be the same size as the screen
const int WORLD_Y = 64;

enum Pixel_Types {
    AIR,
    WALL,
    DIRT,
    STONE
};

class Pixel
{
    int x, y;
    bool affected_by_gravity;
    Pixel_Types type;
    public:
        Pixel() : affected_by_gravity(false), type(AIR), x(0), y(0) {}
        Pixel(int temp_x, int temp_y) : affected_by_gravity(false), type(AIR), x(temp_x), y(temp_y) {}

        int getX() { return x; } //x is 0-63, scales up in the rendering code
        int getY() { return y; } //y is 0-63, scales up in the rendering code

        int getScreenX() { return x*PIXEL_WIDTH; } //x is 0-63, scales up in the rendering code
        int getScreenY() { return y*PIXEL_HEIGHT; } //y is 0-63, scales up in the rendering code

        bool setDeltaX(int temp_delta_x);
        bool setDeltaY(int temp_delta_y);

        void setAffectedByGravity(bool yesorno) { affected_by_gravity = yesorno; }
        bool getAffectedByGravity() { return affected_by_gravity; }

        Pixel_Types getType() { return type; }
        void setType(Pixel_Types what_type) { type = what_type; }//if (type == DIRT or type == STONE) { affected_by_gravity = true; } }
};

std::vector<Pixel> world; //the world is a dynamically allocated thing

Pixel* getPixelFromCoordinates(int x, int y)
{
    if (x > 63) x = 63;
    else if (x < 0) x = 0;
    if (y > 63) y = 63;
    else if (y < 0) y = 0;

    for (int pixel_index = 0; pixel_index < world.size(); pixel_index++) {
        if (world.at(pixel_index).getX() == x && world.at(pixel_index).getY() == y) {
            return &world.at(pixel_index);
        }
    }
    return NULL;
}

bool Pixel::setDeltaX(int temp_delta_x) {
    if (x+temp_delta_x > SCREEN_WIDTH/PIXEL_WIDTH or x+temp_delta_x < 0) {
        return false;
    }
    if (getPixelFromCoordinates(x+temp_delta_x, y)->type == AIR) {
        x += temp_delta_x; 
        return true;
    }
    return false;
}

bool Pixel::setDeltaY(int temp_delta_y) { 
    if (y+temp_delta_y > SCREEN_HEIGHT/PIXEL_HEIGHT or y+temp_delta_y < 0) {
        return false;
    }
    if (getPixelFromCoordinates(x, y+temp_delta_y)->type == AIR) {
        y += temp_delta_y; 
        return true;
    }
    return false;
}

void generateWorld()
{
    for (int world_generation_index = 0; world_generation_index < 4096; world_generation_index++) {
        int x = world_generation_index % WORLD_X; //the world is 64 pixels left and right, and 64 up and down. this math is pretty easy and just extrapolates that. also each pixel is 10 pixels across, times 64 pixels = 640 (the resolution)
        int y = floor(world_generation_index / WORLD_Y); //both x and y start at 0
        world.push_back(Pixel(x, y));


        if (x == 0 || x == 63) {
            world.at(world_generation_index).setType(WALL);
        }

        if (y == 1) {
            world.at(world_generation_index).setType(WALL);
        }    

    }
    std::cout << "World size: " << world.size() << std::endl;
}

void createPixel(int x, int y, Pixel_Types type) 
{
    std::cout << x << std::endl;
    std::cout << y << std::endl << std::endl;
    y = (SCREEN_HEIGHT / PIXEL_HEIGHT) - y; //compensate for the stupid inverted y in opengl
    //if (getPixelFromCoordinates(x, y)->getType() == AIR) {
        getPixelFromCoordinates(x, y)->setType(type);
    //}
}

void physicsOneStep() 
{
    for (int pixel_index = 0; pixel_index < world.size(); pixel_index++) {
        if (world.at(pixel_index).getType() == DIRT or world.at(pixel_index).getType() == STONE) {//if (world.at(pixel_index).getAffectedByGravity()) {
            world.at(pixel_index).setDeltaY(-1);
            //std::cout << world.at(pixel_index).getX() << std::endl;
            //std::cout << world.at(pixel_index).getY() << std::endl << std::endl;
        }
    }
}

因此,当我尝试运行此代码(较大项目的一部分)时,它偶尔会在setType(DIRT)内调用createPixel()时给我一个Segfault。我知道提供给createPixel()的值在允许的范围内(0到64)。如果您在同一位置点击两次(在createPixel()中调用void setType(Pixel_Types what_type) { type = what_type; }),似乎会出现段错误。调试器说segfaults的行是

{{1}}

但是,我已经确认我提供的值是正确的。

1 个答案:

答案 0 :(得分:1)

由于类中没有动态分配,因此{Q}}指针本身不正确(NULL或分配不当),肯定会出现这种分配的段错误。您应该在进行segfaulted时查看回溯,以查看您调用this的对象是如何分配的。例如,不应该行

setType

world.push_back(Pixel(x, y));