为什么在读取私有类变量时会得到EXC_BAD_ACCESS

Why do I get an EXC_BAD_ACCESS when reading back a private class variable?

本文关键字:EXC BAD ACCESS 读取 类变量 为什么      更新时间:2023-10-16

我有一个Rectangle类,如下所示:

标题:

class Rectangle: public Polygon {
private:
    float _width, _height;
public:
    Rectangle(float width, float height);
    float getWidth(float* width) const;
    float getHeight(float* height) const;
    bool isCollidingWith(Rectangle* other) const;
};

选定实施:

Rectangle::Rectangle(float width, float height) : Polygon(explodeRect(width, height, new struct vertex[4]), 4) {
    printf("creating rect %f x %fn", width, height);
    _width = width;
    _height = height;
    printf("set _width to %fn", _width);
}
float Rectangle::getWidth(float* width) const {
    printf("_w: %fn", _width);
    *width = _width;
    return *width;
    //return (*width = _width);
}
float Rectangle::getHeight(float* height) const {
    return (*height = _height);
}

我初始化了Rectangle类的一个实例,输出指示_width变量被正确分配。然而,当我稍后尝试使用getWidth方法读取变量时,我在以下行中得到了EXC_BAD_ACCESS错误:

printf("_w: %fn", _width);

为什么我不能再读取这个变量了?对于_height变量,我也遇到了同样的问题。

编辑:我还想注意的是,如果我跳过读取宽度,我会在尝试直接从对象读取公共变量时出错,例如,当我尝试用obj->x读取其x位置时。

编辑2:这可能是因为对象是Rectangle的子类的实例,而这个子类是在与Rectangle不同的文件中定义的吗?我还在读取第三个文件中的值。

编辑3:下面是更多代码。

我正在尝试用OpenGL重新创建俄罗斯方块。在我的display方法中,我有以下代码来绘制矩形:

if(fallingBlock != nullptr) {
    printf("drawing falling block at (%f, %f)n", fallingBlock->x, fallingBlock->y);
    draw(fallingBlock);
}

fallingBlock被定义为我的文件顶部的全局变量:

Block* fallingBlock;

从我的main,我调用了一个initVars方法,该方法随后调用了startDroppingBlock方法。这是:

void startDroppingBlock() {
    Block* block = availableBlocks[random() % numAvailableBlocks].copy();
    block->x = 0.5;
    block->y = SCREEN_TOP;
    block->dy = -0.01f;
    //printf("copied block is at (%f, %f)n", block->x, block->y);
    fallingBlock = block;
}

这是我的方块图绘制方法:

void draw(Block* obj) {
    bool shape[3][3];
    obj->getShape(shape);
    //printf("got shape: {%d, %d, %d}, {%d, %d, %d}, {%d, %d, %d}n", shape[0][0], shape[0][1], shape[0][2], shape[1][0], shape[1][1], shape[1][2], shape[2][0], shape[2][1], shape[2][2]);
    /*float pieceWidth;
    obj->getWidth(&pieceWidth);
    pieceWidth /= 3.0f;*/
    float pieceWidth = obj->getWidth();
    for(unsigned int i=0; i<3; i++) {
        for(unsigned int j=0; j<3; j++) {
            if(shape[i][j]) {
                Square rect = Square(pieceWidth);
                rect.x = obj->x + pieceWidth * j;
                rect.y = obj->y + pieceWidth * i;
                rect.color = obj->color;
                draw(&rect);
            }
        }
    }
}

我在[…]行收到EXC_BAD_ACCESS错误。为什么我不能再读取此变量?_height变量也有同样的问题。[稍后…]我已经尝试了float pieceWidth; obj->getWidth(&pieceWidth);obj->getWidth(new float)——实际错误在我读取_width的那一行,甚至在我使用传入指针之前。[稍后…]我修改了getWidth和getHeight方法,只返回_width和_height。现在我在return _width;

在这种情况下,我看到您使用的是Rectangle*指针作为obj->getWidth,如果obj不是有效指针,也可能导致错误的访问错误。


需要注意的是,我根本不太理解你的getter方法。它的简化版本(可能是标准)可能是:

float Rectangle::getWidth() const {
    return _width;
}

唯一的区别是,当你使用时:

// float a;
// float b;
a = rect.getWidth(&b);

你现在可以做:

// float a;
// float b;
a = b = rect.getWidth();

这可能更干净,并且肯定不会造成这样的错误。一个很好的经验法则是尽可能不要使用指针。如果需要修改函数中的变量,只需使用引用即可。