简体   繁体   English

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

[英]Issue with struct constructor causing stack overflow

Both sections of code below are drastically simplified, isolated versions of my actual code. 下面的代码两部分都是我实际代码的大大简化的隔离版本。 The examples are just big enough to reproduce the problem. 这些示例足够大,可以重现该问题。 The first section of code below works fine. 下面的代码的第一部分工作正常。 The section section is an attempt to begin to make it part of a class. 本节是试图开始使其成为类的一部分。 I'm trying to take tiny steps since small modifications to something like the struct shown below require lots of changes throughout the code which is full of pointers, pointer to pointers and references which all involve this struct. 我正在尝试采取一些小步骤,因为对如下所示的结构进行小的修改需要在整个代码中进行很多更改,这些代码充满了指针,指向指针的指针和引用,而这些都涉及此结构。 Can you tell me why the second section of code throws a stack overflow within it's constructor and what small changes can be made to fix it? 您能告诉我为什么第二部分代码在其构造函数中引发堆栈溢出,并且可以进行一些小的更改来修复它吗?

Working code: 工作代码:

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

Attempt to very gradually modify the code as a whole toward becoming a 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;
}

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

It is because in working version you have reference to an array of object, but not actual object of Items . 这是因为在工作版本中,您引用的是对象数组,而不是Items实际对象。 In second version, you are creating objects by using keyword new . 在第二个版本中,您正在使用关键字new创建对象。 So, in second version in constructor it will call itself! 因此,在构造函数的第二个版本中,它将自行调用! It will call it's own constructor infinite times. 它将无限次调用它自己的构造函数。 Hence, you see runtime exception stackoverflow :) 因此,您会看到运行时异常stackoverflow :)

All the answers are right. 所有答案都是正确的。 I want to suggest a solution for you: Instead of initializing the array within the ctor, you could implement an initialization method like 我想为您提供一个解决方案:您可以实现类似以下方法的初始化方法,而不是在ctor中初始化数组:

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

that you can call after having constructed the object. 构造对象后可以调用的对象。 This should avoid the stack overflow. 这应该避免堆栈溢出。 In general, you should avoid to place instances of an object inside the object itself. 通常,应避免将对象实例放置在对象本身内部。 Its better to use Collections of the Item List<Item>, std::vector<Item>, ... 最好使用Item List<Item>, std::vector<Item>, Collection。

Above posters are right. 以上海报是正确的。 Within the constructor of Item you create items (by creating an array). Item的构造函数中,您可以创建项目(通过创建数组)。 So the ctor is again called, which creates more items, which .... This is more or less an infinite loop which eats up your stack. 因此,再次调用了ctor,它创建了更多的项目,.....这或多或少是一个无限循环,吞噬了您的堆栈。 Either stick with the references or use a collection like List - so you can add the items later on dynamically. 要么坚持引用,要么使用诸如List类的集合-这样您就可以在以后动态添加项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM