0

我正在编写一个程序来展示康威在 C++ 中的生命游戏。我的教授给了我们一个主函数和一个描述“宇宙”的类,我们必须实现类中原型化的函数。我现在的问题实际上是让构造函数起作用。我将发布课程,然后是我为构造函数编写的内容。当我到达使用构造函数的第一行时使用 GDB (universe(width, height, wrap);) 我收到以下错误:libc++abi.dylib: terminate called throwing an exception

程序收到信号 SIGABRT,已中止。0x00007fff876fad46 in __kill()

任何帮助表示赞赏!代码如下。

    // 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;
}
4

2 回答 2

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

于 2013-04-18T02:10:52.123 回答
1

原始代码有很多问题,很难从列表中删除,但我可以尝试:

  1. 成员widthheight用于成员分配大小,甚至在它们包含确定值之前。因此它们的值使用是不确定的,因此内存分配表现出未定义的行为

  2. 分配被存储到本地指针,然后在退出构造函数后立即丢失。它永远不会分配给成员变量 array。因此,您正在泄漏内存。此外,由于array(成员)从未被分配,因此即使在构造之后,它的值也是不确定的,因此使用它包含的地址的任何访问(读取或写入)都是未定义的行为

  3. 您没有类析构函数来清理在构造函数或成员函数中分配的内存。(假设您正确修复了 3-param 构造函数,并且它实际上内存分配指针保存在array成员中)。因此,这会在销毁(假设 3-param 构造函数是固定的)或构造时(假设 3-param 构造函数不固定)泄漏内存。

  4. widthheight成员目前可以接受负值,这对于实际使用没有意义,并且会对您的分配造成潜在的破坏。所有不打算显式允许负值的成员都应该是无符号类型,size_t这是常见的。

  5. 两个构造函数都没有初始化列表。他们都应该。

  6. class universe为局部成员变量动态分配内存。在不建立虚拟析构函数、复制构造函数和赋值运算符的情况下,将提供编译器默认实现,并且它们肯定会导致内存泄漏或内存损坏。这段代码应该实行三法则,目前没有。

  7. 您当前在 3-param 构造函数中的分配大小逻辑偏离了一个元素。(-1) 不属于那里,紧随其后的循环将写入一个超出分配大小的元素。这是未定义的行为

  8. 您正在使用标准库定义的类的名称作为本地定义的变量/类/成员的名称。虽然不是正式的“错误”,但强烈建议您避免这种做法。

强烈建议一本可靠的 C/C++ 书籍

于 2013-04-18T02:34:44.293 回答