【问题标题】:Initialize C++ struct on the heap instead of the stack在堆而不是堆栈上初始化 C++ 结构
【发布时间】:2017-05-27 19:39:54
【问题描述】:

出于我不想进入这里的原因,我必须将在其他地方编写的一些代码集成到我们的程序中,而对其代码的更改最少。该代码有一个构造函数,它创建一个结构作为局部变量(在堆栈上),然后将其分配给一个成员变量,如下所示:

struct S
{
   // lots of real_T's and uint32_T's and structs and structs within structs
};

class C
{
private:
   S s;
   // among other members
};

C::C()
{
   S tempS = {
      // more than 52k lines of code!!!
   };
   s = tempS;
}

他们的代码是从某种 Matlab 模型自动生成的,是的,该结构的初始化程序中有超过 52,000 行代码。 由于明显的原因,它会导致堆栈溢出,这是我要解决的实际问题。

C 类正在堆上创建(实际上它是从 C 派生的类的包装器),我的理解是这意味着 C.s 也在堆上。

请注意,我们目前使用的是 Visual Studio 2010,但我们将很快迁移到 Visual Studio 2015(TM),因此适用于任何一种的解决方案都可以。

问题

  1. 有没有办法直接初始化C.s?

  2. 或者有没有一种方法可以在将 tempS 复制到 C.s 之前在堆上创建它,而无需重写 52k 行初始化程序代码?

这些方法似乎都不适合我:http://en.cppreference.com/w/cpp/language/value_initialization

(6) 看起来像我想要的:

S * tempS = new S {
    // more than 52k lines of code!!!
};

但它会导致编译错误:“error C2143: syntax error: missing ';'在'{'”之前

【问题讨论】:

  • 发生了什么是你直接在成员初始化列表中初始化s
  • 一个结构中的 52k 行?哇。但是您可以将您的尝试 S * tempS = new S {... 修改为 S * tempS = new S; 并使用 S->var = ... 初始化每个成员
  • 那“超过 52k 行代码!!!”评论实际上把我吓坏了。代码有味道,有人吗?
  • 我想您的另一个选择是增加程序的堆栈大小。
  • VS2010 已经过时,它可能理解也可能不理解new S { ... } 语法。移到 2015 年。

标签: c++ struct heap-memory stack-overflow


【解决方案1】:

有没有办法直接初始化C.s?

是的,只需替换此代码:

C::C()
{
   S tempS = {
      // more than 52k lines of code!!!
   };
   s = tempS;
}

用这个:

C::C() :
   s {
      // more than 52k lines of code!!!
   }
{
}

你可以see here 它应该在支持 C++11 或更高版本的编译器上工作

【讨论】:

  • 我试过了,但没有用。它在第一个'{'处给出编译错误。
  • 如果你的编译器支持C++11它应该可以工作,你说你可以切换到2015,那就这样做吧。
【解决方案2】:

我会考虑将tempS 设为C 的私有静态常量成员(并在另一个编译单元中定义它)。这个初始化器/原型基本上是数据,只是使代码不可读。此外,无论您在何处/如何定义,这些数据都在您的二进制文件中的某个位置,因此您不妨明确说明。

【讨论】:

  • 这成功了!我刚刚将S tempS = { 更改为static const S tempS = {(请参阅上面的原始示例)。感谢您的帮助!
  • 我有时会忘记我们的选择不仅限于堆与堆栈。我最近阅读了一篇文章(或 Stack Overflow 的答案?),讨论了将内容分配到不同内存区域的不同方法,但我忘记了在哪里。
【解决方案3】:

我的建议是在S 类中创建一个构造函数,它将所有成员的值作为参数。按照结构中定义的顺序定义构造函数的参数列表。

struct S
{
   // lots of real_T's and uint32_T's and structs and structs within structs
   S(/*parameter_lsit*/) : /*initializer_list*/ {}
};

并像初始化它一样 -

S * tempS = new S (
    // more than 52k lines of code!!!
);

【讨论】:

  • 不幸的是,这需要为初始化列表重写 52k 行代码。
猜你喜欢
  • 2013-04-11
  • 1970-01-01
  • 2018-04-06
  • 1970-01-01
  • 1970-01-01
  • 2017-02-24
  • 2023-04-09
  • 2018-04-11
  • 2016-08-13
相关资源
最近更新 更多