以下两段代码都是我实际代码的大大简化的隔离版本。这些例子足以重现问题。下面的第一部分代码工作正常。部分部分试图开始使其成为课程的一部分。我试图采取微小的步骤,因为对下面显示的结构进行小的修改需要在整个代码中进行大量更改,这些更改充满了指针,指针指针和引用都涉及此结构。你能告诉我为什么代码的第二部分会在它的构造函数中引发堆栈溢出,并且可以做些什么微小的修改来修复它?
工作代码:
#include <cstdio>
#include <cstdlib>
#include <iostream>
using std::cout;
using std::endl;
const int maxSize = 3;
struct Item{
int count;
Item *items[maxSize + 1];
};
void foo()
{
Item *p;
p = new Item();
p->count = 2;
cout << p->count << endl;
}
int main(int argc, char *argv[])
{
foo();
return 0;
}
尝试逐步修改整个代码以成为一个类:
#include <cstdio>
#include <cstdlib>
#include <iostream>
using std::cout;
using std::endl;
int maxSize = 3;
struct Item{
int count;
Item *items;
Item()
{
items = new Item[maxSize + 1]; // stack overflow
}
};
void Initialize(int size)
{
maxSize = size;
}
void foo()
{
Item *p;
p = new Item();
p->count = 2;
cout << p->count << endl;
}
int main(int argc, char *argv[])
{
Initialize(5);
foo();
return 0;
}
答案 0 :(得分:2)
构造Item
调用new Item[maxSize+1]
的第一个调用,调用默认构造函数,调用new Item[maxSize+1]
,调用默认构造,依此类推,直到达到堆栈溢出。
答案 1 :(得分:1)
这是因为在工作版本中你引用了一个对象数组,而不是Items
的实际对象。在第二个版本中,您使用关键字new
创建对象。所以,在构造函数的第二个版本中,它将调用自己!它会无限次地称它为自己的构造函数。因此,您会看到运行时异常stackoverflow:)
答案 2 :(得分:1)
所有答案都是正确的。我想为您推荐一个解决方案: 您可以实现像
这样的初始化方法,而不是在ctor中初始化数组init(int maxSize) {
items = new Item[maxSize + 1];
}
您可以在构造对象后调用。这应该避免堆栈溢出。通常,您应该避免将对象的实例放在对象本身内。最好使用项目的集合
List<Item>, std::vector<Item>,
...
答案 3 :(得分:0)
以上海报是对的。在Item
的构造函数中,您可以创建项目(通过创建数组)。所以再次调用ctor,它会创建更多项目,这......或多或少是一个无限循环,它会占用你的堆栈。
要么坚持使用引用,要么使用像List
这样的集合 - 这样您就可以在以后动态添加项目。