C++新手,我不明白"EXC_BAD_ACCESS"错误
New to C++, "EXC_BAD_ACCESS" error I don't understand
我正在尝试将一个二维元胞自动机从Processing转换为openFrameworks(C++(。我已经为细胞和生命游戏功能编写了课程。应用程序成功构建,但立即崩溃,并出现以下错误:线程1:程序接收到信号:"EXC_BAD_ACCESS"。
这是我的标题我的生活类游戏
#include "Cell.h"
class GoL {
public:
GoL();
void init();
void generate();
void display();
void run();
int w = 20;
int cols;
int rows;
std::vector<vector<cell> > board;
};
这里是实现:
#include "GoL.h"
GoL::GoL() {
cols = ofGetWidth() / w;
rows = ofGetHeight() / w;
board[rows][cols];
init();
}
void GoL::run() {
generate();
display();
}
void GoL::init() {
for (int i = 0; i < cols; i ++) {
for (int j = 0; j < rows; j ++) {
board[i][j] = *new cell(i * w, j * w, w);
}
}
}
void GoL::generate() {
for (int i = 0; i < cols; i ++) {
for (int j = 0; j < rows; j ++) {
board[i][j].savePrevious();
}
}
for (int x = 0; x < cols; x ++) {
for (int y = 0; y < cols; y ++) {
int neighbours = 0;
for (int i = -1; i <= 1; i ++) {
for (int j = -1; j <= 1; j ++) {
neighbours += board[(x + i + cols) % cols][(y + j + rows) % rows].previous;
}
}
neighbours -= board[x][y].previous;
// Rules of Life
if ((board[x][y].state == 1) && (neighbours < 2)) board[x][y].newState(0);
else if ((board[x][y].state == 1) && (neighbours > 3)) board[x][y].newState(0);
else if ((board[x][y].state == 0) && (neighbours == 3)) board[x][y].newState(1);
}
}
}
void GoL::display() {
for (int i = 0; i < cols; i ++) {
for (int j = 0; j < rows; j ++) {
board[i][j].display();
}
}
}
错误显示在vector.h文件、GoL头文件以及我在GoL实现中调用init((方法的地方。非常感谢您的帮助。
这里有一个越界访问,因为向量的大小为0:
board[rows][cols];
您可以在构造函数初始化列表中初始化向量,如下所示:
GoL::GoL() : cols(ofGetWidth()/w), rows(ofGetHeight()/w), board(rows, std::vector<cell>(cols))
{
}
这将把board
初始化为大小rows
,并且它的每个元素将是大小cols
的向量。然后您可以为其元素赋值:
cell c = ...;
board[i][j] = c;
由于您的向量未初始化,您肯定有一个越界访问。从技术上讲,你的向量是初始化的,但只是作为一个空容器,这意味着你应该保留足够的单元来将它及其包含的向量视为一个2d数组,因此必须a(在循环中添加单元b(使用范围构造函数c(使用对元素数量进行计数的构造函数。更多信息请点击此处。
最好始终确保您的类型在构造函数结束时可用。更喜欢在构造函数初始化列表中初始化您可以初始化的内容,并将构造函数范围用于任何需要更多逻辑的内容。如果您的类型不能始终构造,请充分考虑命名构造函数习惯用法。基本上,您只是从静态或非成员朋友函数返回一个句柄,允许您为不成功的创建返回一个sentinel值(也称为NULL,表示指针(。
听起来您还需要考虑C++类型的系统是如何工作的。
除非您的类型"cell"是某个数据类型的句柄,或者只是POD类型,否则您可能希望在向量中存储对堆分配对象的引用,而不是cell对象的副本。
若单元格必须像多态类型一样处理(您希望将其用作基类(,则需要在向量中存储某种形式的句柄,例如指针或更好的智能指针。
如果你使用C++11,你可以使用一个新的内置智能指针,或者你可以随时使用boost。
关键的一点是,您应该更喜欢使用RAII实践来避免悬挂引用。尽管C++没有内置的垃圾收集器,但您可以使用RAII原理实现一个非常稳定的产品。主要要避免的是循环引用,这可以通过使用对关系的弱引用来减轻,在这种关系中,您不需要引用保持活动。一个常见的例子是,当您有一个对象层次结构时,父类持有对子级的引用,而子级则持有对父级的引用。孩子们可能不需要对父母的有力引用,因为当父母这样做时,他们会超出范围。
- 将数组信息存储到 c++ 向量中有一个"Access violation reading location"
- 为什么调试器引发"read access violation. this was nullptr"异常?
- 在 Microsoft Access SQL 中调用自定义 DLL 函数时传递的内存地址无效
- Simulink "Access Violation"写入 C++ lambda 函数捕获列表中的 PWork 变量
- Qt QXmlStreamReader Access Violation
- "Access is Denied" U盘上的创建文件()
- 指向 std::unrodered_map 中元素的指针返回'Read access violation'
- 例外:'Access violation reading location'
- 向量数组"Cannot access memory at address"
- Windeployqt不会运行,"Access is denied."
- 我在发布模式下运行时收到"Access violation reading location"错误 - C++
- Access C++ Enum from Swift
- Java 本机访问代码错误:"Invalid memory access"
- 如何获得私人会员的"read access"?
- 将数据添加到 CArray 会产生错误"cannot access private member declared in class 'CObject'"
- C++:分析包含表达式的字符串"access to the multidimensinal array"
- 如何修复我的 c++ 毕达哥拉斯三重查找器中的'access violation reading location'错误?
- C 和WXWIDGETS DLL创建并与Microsoft Access一起使用
- 矩阵 - "Access violation writing location 0x00900B0C" - C++ 中的错误
- Windows 10 中的 MS Access 数据库 SQL 查询问题