导致堆栈溢出的结构构造函数问题
Issue with struct constructor causing stack overflow
下面的两部分代码都大大简化了我的实际代码的独立版本。这些示例足够大以重现问题。下面的第一部分代码工作正常。 section section 试图开始使它成为class的一部分。我试图采取微小的步骤,因为对像下面所示的结构这样的东西的小修改需要在整个代码中进行大量更改,这些代码充满了指针、指向指针的指针和引用,这些都涉及到这个结构。你能告诉我为什么第二部分代码在它的构造函数中抛出堆栈溢出吗?可以做哪些小的改变来修复它?
工作代码:
#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;
}
尝试逐步修改整个代码以成为 class:
#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;
}
这是因为在工作版本中你引用了一个对象数组,而不是 Items
的实际对象。在第二个版本中,您使用关键字 new
创建对象。因此,在构造函数的第二个版本中,它将调用自身!它会无限次调用它自己的构造函数。因此,您会看到运行时异常 Whosebug :)
构造 Item
的第一个调用调用 new Item[maxSize+1]
,它调用默认构造函数,它调用 new Item[maxSize+1]
,它调用默认构造,依此类推,直到到达堆栈溢出。
以上海报是正确的。在 Item
的构造函数中,您创建项目(通过创建数组)。所以 ctor 再次被调用,它创建更多的项目,...。这或多或少是一个无限循环,它会耗尽你的堆栈。
要么坚持引用,要么使用像 List
这样的集合 - 这样您就可以稍后动态添加项目。
所有答案都正确。我想为您建议一个解决方案:
您可以实现一个初始化方法,例如
,而不是在构造函数中初始化数组
init(int maxSize) {
items = new Item[maxSize + 1];
}
可以在构造对象后调用。这应该避免堆栈溢出。通常,您应该避免将对象的实例放置在对象本身内部。最好使用项目的集合
List<Item>, std::vector<Item>,
...
下面的两部分代码都大大简化了我的实际代码的独立版本。这些示例足够大以重现问题。下面的第一部分代码工作正常。 section section 试图开始使它成为class的一部分。我试图采取微小的步骤,因为对像下面所示的结构这样的东西的小修改需要在整个代码中进行大量更改,这些代码充满了指针、指向指针的指针和引用,这些都涉及到这个结构。你能告诉我为什么第二部分代码在它的构造函数中抛出堆栈溢出吗?可以做哪些小的改变来修复它?
工作代码:
#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;
}
尝试逐步修改整个代码以成为 class:
#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;
}
这是因为在工作版本中你引用了一个对象数组,而不是 Items
的实际对象。在第二个版本中,您使用关键字 new
创建对象。因此,在构造函数的第二个版本中,它将调用自身!它会无限次调用它自己的构造函数。因此,您会看到运行时异常 Whosebug :)
构造 Item
的第一个调用调用 new Item[maxSize+1]
,它调用默认构造函数,它调用 new Item[maxSize+1]
,它调用默认构造,依此类推,直到到达堆栈溢出。
以上海报是正确的。在 Item
的构造函数中,您创建项目(通过创建数组)。所以 ctor 再次被调用,它创建更多的项目,...。这或多或少是一个无限循环,它会耗尽你的堆栈。
要么坚持引用,要么使用像 List
这样的集合 - 这样您就可以稍后动态添加项目。
所有答案都正确。我想为您建议一个解决方案: 您可以实现一个初始化方法,例如
,而不是在构造函数中初始化数组init(int maxSize) {
items = new Item[maxSize + 1];
}
可以在构造对象后调用。这应该避免堆栈溢出。通常,您应该避免将对象的实例放置在对象本身内部。最好使用项目的集合
List<Item>, std::vector<Item>,
...