在类内初始化数组会产生 std::bad_alloc 错误,但在外面不会?

Posted

技术标签:

【中文标题】在类内初始化数组会产生 std::bad_alloc 错误,但在外面不会?【英文标题】:Initializing array inside class gives std::bad_alloc error, but outside doesn't? 【发布时间】:2018-04-26 17:53:48 【问题描述】:

我有一个程序有两个类(我称它们为 Master 和 Slave),Slave 继承自 Master。在 Slave 中,我定义了一个结构,以及该结构类型的可能值的数组。然后使用我想从 Master 类中填充变量的数组的索引来实例化 Slave。

像这样:

class Master

public:
    std::string _a;
    char _b;
    int _c;
    int _d;
    int _e;

    Master(std::string a, char b, int c, int d, int e)
        : _a a, _b b, _c c, _d d, _e e 
;

class Slave : public Master

public:
    struct SlaveStruct
    
        std::string a;
        char b;
        int c;
        int d;
        int e;
    ;

    const SlaveStruct slaveArray[3]
    
        "name_a", 'A', 1, 2, 3,
        "name_b", 'B', 4, 5, 6,
        "name_c", 'C', 7, 8, 9
    ;

    Slave(int index) : Master slaveArray[index].a, slaveArray[index].b, 
        slaveArray[index].c, slaveArray[index].d, slaveArray[index].e 
;

但是,当我尝试实例化它时,它会发出 std::bad_alloc 错误。乱七八糟,我发现它工作得很好,但是如果我只是在类中声明数组,然后在外面初始化它,如下所示:

class Slave : public Master

    //(...)

    static SlaveStruct slaveArray[3];

    //(...)
;

Slave::SlaveStruct Slave::slaveArray[3]

    "name_a", 'A', 1, 2, 3,
    "name_b", 'B', 4, 5, 6,
    "name_c", 'C', 7, 8, 9
;

为什么会这样呢?这个数组的大小是 144 字节,它几乎不会在堆栈中产生任何影响,而且我只实例化了一次该类。尝试调试它,但是在进入 Slave 构造函数之后,它进入了一个我无法理解的 C++ 原生函数的深坑,很快就抛出了 bad_alloc 错误。

更新:根据 cmets 中的要求,将类实例化为:

int main()

    Slave slave 1; // For example, any index will throw the same error.

平台:Windows 10、MSVC 2017。

【问题讨论】:

请说明你是如何实例化坏版本的。 你应该在构造函数中初始化slaveArray 【参考方案1】:

先调用基类构造函数,再构造成员。

Master slaveArray[index].a,... 中,您尝试将slaveArray[index].a 传递给基类的构造函数,但此时slaveArray 尚未初始化。因此,您的程序表现出未定义的行为。

相比之下,静态成员在程序启动时初始化,在输入main之前。这就是为什么您的第二个示例运行良好的原因。

【讨论】:

谢谢@IgorTandetnik,这很有见地!

以上是关于在类内初始化数组会产生 std::bad_alloc 错误,但在外面不会?的主要内容,如果未能解决你的问题,请参考以下文章

Static在类中的作用

1.类中数据成员的声明与初始化总结

C++中静态成员变量的可以在类内初始化吗?

在类内设置参数,Null 对象

为什么static成员必须在类外初始化,而不能在类的头文件中初始化

为什么static成员必须在类外初始化