结构构造函数导致堆栈溢出的问题

Issue with struct constructor causing stack overflow

本文关键字:栈溢出 问题 堆栈 构造函数 结构      更新时间:2023-10-16

下面的两段代码都是我实际代码的简化、孤立版本。这些示例足够大,可以重现问题。下面的第一部分代码工作正常。节部分是开始使其成为类的一部分的尝试。我正在尝试采取一些小步骤,因为对下面显示的结构之类的小修改需要在整个代码中进行大量更改,这些代码充满了指针、指向指针的指针和引用,这些都涉及此结构。你能告诉我为什么第二段代码在其构造函数中抛出堆栈溢出以及可以进行哪些小的更改来修复它吗?

工作代码:

#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;
}
构造

Item的第一个调用调用new Item[maxSize+1],它调用默认构造函数,调用new Item[maxSize+1],调用默认构造,依此类推,直到达到堆栈溢出。

所有的答案都是正确的。我想为您提出一个解决方案:与其在 ctor 中初始化数组,不如实现一个初始化方法,例如

init(int maxSize) {
  items = new Item[maxSize + 1];
}

您可以在构造对象后调用。这应该可以避免堆栈溢出。通常,应避免将对象的实例放在对象本身内。最好使用项目的集合 List<Item>, std::vector<Item>,......

这是因为在工作版本中,您引用了一个对象数组,而不是Items的实际对象。在第二个版本中,您将使用关键字 new 创建对象。因此,在构造函数的第二个版本中,它将调用自己!它将无限次调用它自己的构造函数。因此,您会看到运行时异常堆栈溢出:)

上面的海报是正确的。在Item的构造函数中,您可以创建项(通过创建数组)。所以再次调用 ctor,它会创建更多项目,这....这或多或少是一个无限循环,会吞噬你的堆栈。要么坚持引用,要么使用像 List 这样的集合 - 这样您就可以在以后动态添加项目。