我想知道堆栈的大对象有多大?如果我们谈论普通PC(Windows或某些Linux)。我试图找到答案,但我发现如果对象太大,我会在堆上进行分配。但是什么太大了?很少KB?还是几百KB?我知道这通常不是问题,但是因为我不知道答案而困扰我。
一些代码:
int main()
{
int a[1000][300]; /* enough for stack overflow :) on Visual Studio 2012 without any specific setting. int a[1000][250] is Ok */
return 0;
}
更多:
int main()
{
MySmallClass a; // I want to use RAII
MyBigClass b; // ouch I shouldn't do it
unique_ptr<MyBigClass> c(new MyBigClass()) // So I would do something like this to keep RAII
return 0;
}
由于Visual Studio似乎只有1MB的堆栈分配问题,所以在堆栈对象上分配最大大小为几KB的问题似乎是合理的,因为堆栈可以非常深入。它并不多,第三方对象我甚至不知道(因为我根本不想知道)它们有多大我只能期望它们合理的小。
当我制作大型静态数组来测试某些性能时,我实际上只遇到过这种问题。所以在现实生活中它可能不是常见问题,但仍然......
答案 0 :(得分:0)
这个问题没有简单的答案。
单个物体?
一些运行时确定的数量?
对象是在每个循环或递归调用中创建的吗?
由于堆栈溢出很难识别,所有这些选择都会影响您在选择将大对象放入堆栈时的谨慎程度。
在我所使用的嵌入式系统中,堆栈与堆很少被讨论。相反,问题只是“对象的生命周期是什么”。
而且,也许令人惊讶的是,大多数“重要”物品都是在启动时创造的,并且从未被破坏过。即它们一直持续到系统重置或断电。
在该嵌入式环境中,重要对象位于堆中。
当然,在实体系统中,还有许多对象只持续到函数(或方法)的末尾。
这些短期对象将适合(或不适合)与使用它们的单个线程关联的堆栈。在该版本的vxWorks中没有运行时堆栈大小更改机制(我知道)。每个任务(我认为对应于linux线程)都有一个在编译时确定的堆栈大小。而且我们偶尔会溢出堆栈。
当你发现并说服自己在你的程序中有堆栈溢出时,有2个解决方案(或者更多)
在一个特定情况下,我的团队的决定是扩展特定的线程堆栈大小。溢出是该线程独有的。
在其他几个方面,我们在函数开头将对象新增到堆中,并在退出时将其删除。简单,对吧?
这是唯一的两个选择吗?也许。
所以,如果你必须有一个号码,我会说找别人的其他经验法则。
作为嵌入式系统的实践开发者,我会将我的选择描述为:
我在堆上保留了非平凡的对象。
堆叠中的少量任何相对简单的物体。
生命周期问题只能将事物从堆栈推送到堆
更大的尺寸只能将东西从堆栈推送到堆
就个人而言,我很乐意使用新的和删除,并对所有权问题有意见。但是......我的'风格'选择不适合每个人。并且有很多文献表明,最终,复杂性会混淆任何知道什么任务拥有什么对象(以及哪个任务应该删除哪些对象)
现在,通过非trival来弄清楚你的意思,简单。
关于std :: vector,std :: strings,std :: stringstream和map's,这些都是相对复杂的对象(恕我直言)。
但是如果你使用sizeof(),即使填充它们也会非常小。我认为这意味着这些都是堆访问的“前端”。
另一方面,它们表现良好,也许正在做其他事情,(与堆不相关)但我还没有调查过。
更多要学习。