静态数组仅在类定义内溢出堆栈(段错误 11),否则不会......?
Posted
技术标签:
【中文标题】静态数组仅在类定义内溢出堆栈(段错误 11),否则不会......?【英文标题】:Static array overflows stack (seg fault 11) only when inside class definition, but not otherwise...? 【发布时间】:2017-04-14 17:56:52 【问题描述】:我想分配一个大的静态数组(--想避免动态分配,例如使用 std::vector,甚至使用'new',所以我可以保证物理地址是连续的并且可以预取有效地)。我的数组大小由外部因素决定,但它们是提前知道的——在这个例子中,我总是需要 3211264 个元素。
如果我只是分配一个浮点数组,一切正常:
#include <iostream>
#include <cstdlib>
using namespace std;
float f[3211264];
int main()
for(int i = 0; i < 3211264; i++)
f[i] = rand();
for(int i = 0; i < 3211264; i++)
cout << f[i];
但是,如果我将数组包装在一个类中,则会导致 Seg 错误:
#include <iostream>
#include <cstdlib>
using namespace std;
class T
public:
T();
private:
float f[3211264];
;
T::T()
for(int i = 0; i < 3211264; i++)
f[i] = rand();
for(int i = 0; i < 3211264; i++)
cout << f[i];
int main()
T myT;
这个内存是如何分配的,当我将数据包装在一个类中时,它有什么不同的原因吗?
我希望类开销最小,并且任何基于对象的重新对齐或填充最多只能是页面侧(4K),对吗?对我来说,这个类主要是为了可读性和组织性,但如果它会对性能产生重大影响,我会放弃它并声明一堆全局变量......
我的编译器信息:
配置为:--prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM 版本 7.3.0 (clang-703.0.29)
目标:x86_64-apple-darwin15.6.0
线程模型:posix
【问题讨论】:
什么是sizeof(T);
?取该值并确定您的程序有多少可用的堆栈空间。
在第一个示例中,f
在堆栈中不。这就是它不超过堆栈的原因。
数组的元素在内存中是连续的,即使是动态分配的。
在连续点上:仅适用于虚拟地址,而不是物理地址,这是硬件预取器关心的...
float f[3211264]
的大小为 12.25 MB。静态内存可以处理那么多数据。堆栈内存不能,除非您在链接器设置中调整堆栈大小。
【参考方案1】:
在将数组设为类成员的代码中,它不是静态分配的。如果你说:
static T myT;
虽然我不敢相信静态分配它会给你带来任何显着的性能提升。
【讨论】:
以上是关于静态数组仅在类定义内溢出堆栈(段错误 11),否则不会......?的主要内容,如果未能解决你的问题,请参考以下文章