【问题标题】:c++ stack overflow unhandled exception with large arrayc ++堆栈溢出未处理的大型数组异常
【发布时间】:2012-05-12 12:59:58
【问题描述】:

是的,查了一下这个问题,我相信这是因为我在我的类定义中有wchar_t downloadedText[400000]; 我已经阅读了关于如何使用new 运算符分配空间来处理这个问题的解决方案, IE: wchar_t *downloadedText; downloadedText = new wchar_t[400000];

但是我需要将类的实例写入文件,并且像上面那样分配变量似乎使用指针指向以不会写入我的文件的方式存储的数据。这也是我不能使用std::vector的原因。

我读过我可能有的另一个选择是我可以增加“堆栈”的大小。我使用 VS2010 作为我的 IDE,我位于我的项目属性 > 链接器 > 系统“堆栈提交大小”、“堆栈保留大小”、“堆提交大小”和“堆保留大小”字段中,但我不确定这是否是我该如何处理我的问题,如果是,正确设置相应字段的内容。

【问题讨论】:

  • 在每种情况下,您如何访问要写入的元素?
  • 您能否用静态数组与指针/向量的编写过程的代码示例更新您的问题?
  • fileOutput.write(reinterpret_cast<char *> (&myObjects[i]), sizeof(MyClass)); 更改类成员时写入文件的过程不会改变(尽管如果我想在添加/删除成员变量后从文件中读取对象数据我将无法这样做)。我显然不能像我不能使用std::string那样使用std::vector,因为它们不直接包含我要写入的数据,而是它们更复杂并且包含指向我想要的实际数据的指针等。跨度>
  • 有指针怎么写?
  • 为什么不写一个合适的写/序列化函数,或者干脆使用一些序列化库? stackoverflow.com/questions/234724/how-to-serialize-in-c

标签: c++ arrays stack-overflow


【解决方案1】:

您可以使用new 运算符在系统堆中分配整个对象,但不能在堆栈中分配。在这种情况下,您可以以相同的方式将此对象写入文件,并且不会出现堆栈溢出的问题。

【讨论】:

  • 我也想到了这个,但是它不喜欢myObjects.push_back(new MyClass(0,0,TEXT("text\0")));的声明它给了我一个类似于error C2664: 'void std::vector<_Ty>::push_back(_Ty &&)' : cannot convert parameter 1 from 'MyClass*' to 'MyClass &&' 1> with 1> [ 1> _Ty=MyClass 1> ] 1> Reason: cannot convert from 'MyClass *' to 'MyClass' 1> No constructor could take the source type, or constructor overload resolution was ambiguous的错误
  • 该错误消息意味着myObjectsstd::vector<MyClass>,您需要将其更改为std::vector<MyClass*>
  • 想一想,如果你把你的对象放入std::vector<MyClass>,那么它们已经在堆上和栈外分配了。
【解决方案2】:

如果你必须这样做......你可以在写出对象之后显式地写数组。例如。

write((char*)&myObjects[i]), sizeof(MyClass));
write((char*)downloadedText, sizeof(downloadedText[0]) * 400000);

然后再读一遍:

read((char*)&myObjects[i]), sizeof(MyClass));
downloadedText = new wchar_t[400000];
read((char*)downloadedText, sizeof(downloadedText[0]) * 400000);

但是,这非常脆弱并且容易出错。通过读取覆盖内存中的对象充其量是不好的形式,除非您使用为此目的显式创建的结构,该结构通常仅包含 POD。作为最低要求,请注意您必须在读取写入后设置下载的文本成员字段。

【讨论】:

  • 我的班级只包含 POD。此外,我更愿意将下载的文本保留为所述类的成员变量。
【解决方案3】:

听起来您对当前的序列化策略很好(制作对象 POD,并将其写入 POD 值)。在这种情况下,您的问题实际上是“如何防止这些对象占用堆栈上的太多空间?”答案:不要把它们放在堆栈上。

用新的分配它们。或者,最好将它们包装在某种智能指针中。


你有类似字符串的数据。碰巧 C++ 提供了一个字符串类。事实上,既然你在谈论wchar_t 字符,你想看看std::wstring(在<string> 标题中)。

【讨论】:

  • 我不能使用 std::string 作为类成员,因为它不是 POD。尝试以二进制模式将其写入文件时会遇到问题。
  • 只有当您尝试将包含 structclass 的文件像 POD 一样写入文件时,您才会遇到问题。如果单独编写每个元素,使用std::wstring 是微不足道的。
  • 我可以很好地编写我的对象的实例,前提是它只有 intchar 等 POD 类型,以及在类中以它们的确切长度声明的数组,即 char myArray[200]尝试只写 std::stringstd::wstring 不起作用,因为它们本身不包含我想要的数据,它们包含指向它的指针等等。
【解决方案4】:

是的,您可以在 Visual Studio 中使用链接器选项/STACK 增加堆栈大小。此链接器选项也可使用项目属性 Stack Reserve SizeStack Commit Size 进行编辑。设置保留大小就足够了,提交大小是可选的。不过你也应该可以使用std::vector

【讨论】:

  • 我最初尝试过这个但没有任何成功。但是,我随后将其设置为更疯狂的值 1024000000(1GB?),因为我没有意识到它似乎在请求以字节为单位的数字。我无法将std::vector 类成员写入我的文件,因为它不是 POD。不幸的是,在出现某种错误的分配错误之前,我只能存储大约 120 个条目。此外,它开始使用相当多的内存,这有点烦人,因为我希望它不要将内存用于所有 400000 个字符,除非它必须这样做。即,如果我不存储任何东西,它应该会占用很少的内存。
猜你喜欢
  • 2012-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-17
  • 1970-01-01
相关资源
最近更新 更多