我正在编写一个程序来展示Conway的C ++游戏。我的教授给了我们一个主函数和一个描述“宇宙”的类,我们必须实现类中的原型函数。我现在的问题实际上是让构造函数正常运行。我将发布该类,然后是我为构造函数编写的内容。当我到达使用构造函数的第一行时使用GDB(universe(width,height,wrap);)我得到以下错误:libc ++ abi.dylib:terminate调用抛出异常
编程接收信号SIGABRT,已中止。 __kill()
中的0x00007fff876fad46任何帮助表示赞赏!代码如下。
// Conways game of life
class universe {
private:
int* array; // A pointer to a [width]X[height] array of cells that constitutes the universe
// for the game of life. A value of 1 signifies a live cell at that location.
int width; // The width of the universe.
int height; // The height of the universe
int wrap; // wrap = 1 means the universe wraps around on itself -- the right hand
// side connects to the left and the top connects to the bottom.
// wrap = 0 means the universe ends at the array boundaries.
public:
universe(); // A null constructor: sets array, width, height, and wrap to 0.
universe(int,int,int); // Constructor to allocate space for a universe of given width (first value)
// height (second value) and wrap setting (third value). Sets all cells to 0.
void display(); // Display the live cells in a graphics window.
void setup(); // Display the universe then allow the user to interactively modify
// the cell arrangement using the mouse.
void operator<<(char*); // Read in a universe from a file; first number has the width,
// second number is the height,
// third number is the wrap parameter,
// then 1s/0s in a 2D integer array represent living/dead cells.
void operator>>(char*); // Save the universe to a file with the specified name (format as above).
void operator=(universe); // Copy the contents of one universe to another.
void operator<<(universe); // Calculate the new generation by applying the rules, then
// display the new generation.
int neighbors(int,int); // Returns the number of neighbors of the cell at i,j.
int value(int,int); // Returns the value at cell i,j (0 or 1).
void setvalue(int,int,int); // Sets the value of the cell at i,j.
void free(); // Release the memory used to store the universe. Set array = 0.
};
// Implementation
universe::universe(){
array =0;
width = 0;
height = 0;
wrap = 0;
}
universe::universe(int width1,int height1,int wrap1){
int i=0, j=0;
int* array = new int[width*height-1];
for(i=0;i<width;i++){
for(j=0;j<height;j++){
array[j*width+i] =0;
}
}
width = width1;
height =height1;
wrap = wrap1;
}
答案 0 :(得分:2)
int* array = new int[width*height-1];
应该是
array = new int[width*height-1];
由于array
是您的类成员,因此不应再次声明具有相同名称的局部变量。否则,您没有初始化类成员array
。局部变量将隐藏类成员。
与此同时,您应首先将值width
和height
分配给new
使用。
您的代码应如下所示:
universe::universe(int width1,int height1,int wrap1){
width = width1;
height =height1;
wrap = wrap1;
array = new int[width*height-1];
for(int i=0; i<width; i++){
for(int j=0; j<height; j++){
array[j*width+i] =0;
}
}
}
如果您想要初始化列表,最好将成员int*array
放在wrap
之后。
答案 1 :(得分:1)
原始代码有很多问题,很难从名单上扯下来,但我可以试试:
成员width
和height
用于成员分配大小调整,甚至包含确定的值。因此,它们的值使用是不确定的,因此内存分配显示未定义的行为。
分配存储到本地指针,然后在退出构造函数后立即丢失。它永远不会分配给成员变量 array
。因此,你正在泄漏记忆。此外,由于永远不会分配array
(成员),因此即使在构造之后其值也是不确定的,因此使用其包含的地址进行的任何访问(读取或写入)都是未定义的行为。 / p>
没有类析构函数来清理构造函数或成员函数中分配的内存。 (假设你正确修复了3-param构造函数,它实际上将内存分配指针保存在array
成员中)。因此,这会在破坏时泄漏内存(假设3参数构造函数是固定的)或构造(假设3参数构造函数未修复)。
您width
和height
成员目前可以接受负值,这对实际使用没有任何意义,并会对您的分配造成潜在的破坏。所有不明确允许负值的成员都应该是无符号类型,size_t
是常见的。
两个构造函数都没有初始化列表。他们都应该。
class universe
为本地成员变量动态分配内存。如果不建立虚拟析构函数,复制构造函数和赋值运算符,将提供编译器默认实现,并且它们最有可能导致内存泄漏或内存损坏。此代码应执行 The Rule of Three ,目前不执行。
3-param构造函数中的当前分配大小逻辑由一个元素关闭。 (-1)不属于那里,紧接着的循环将写入超出分配大小的一个元素。这是未定义的行为。
您使用标准库定义类的名称作为本地定义的变量/类/成员的名称。虽然没有正式“错误”,但强烈建议你可以避免这种做法。
我强烈建议solid C/C++ book。