2013-02-28 75 views
0

我有一个小程序,用C++编写,包含一个大型数组的类。这个类看起来像这样:为什么我的程序在构造函数中使用fread时崩溃?

class Test 
{ 
public: 
    Test(); 
    ... 
private: 
    int myarray[45000000]; 
}; 

现在,这个数组从文件读入。我想直接与构造函数做到这一点,而不是打扰任何额外的功能。该数组只需要一次读入,之后不会再改变。它具有指定的确切大小。

我的构造是这样的:

Test() 
{ 
    memset(myarray, 0, sizeof(myarray)); 
    FILE* fstr = fopen("myfile.dat", "rb"); 
    size_t success= fread(myarray, sizeof(myarray), 1, fstr); 
    fclose(fstr); 
} 

使用Visual Studio 2012旗舰版:当试图启动一个使用这个类的程序,它与“APPCRASH”崩溃只要创建类,和当试图对其进行调试时(我几乎不知道),告诉我该错误是堆栈溢出。

这一切的奥秘在于,在我以前的版本中,myarray是一个静态变量,我不得不调用静态函数来设置它,一切都很顺利。但试图将其转换为构造函数,尽我所能,我所有的尝试都失败了。

那么我在这里做错了什么?

+1

您的课程对于堆栈太大了。尝试在堆中分配数组,而不是在堆栈中分配数组。 – Nick 2013-02-28 13:40:57

回答

3

,所以你可能做到这一点在你的主(或其他地方)

int main() 
{ 
    Test t; // Hello StackOverflow 
} 

你需要的是给它分配在堆上:

int main() 
{ 
    Test* t = new Test; 
    delete t; 
} 

它没有静态变量,因为崩溃静态变量不在堆栈上分配

+4

更好的是,将'myarray'改成一个动态数组(最好是'std :: vector ',所以你不需要自己处理任何内存管理)。然后'Test'的用户不会有任何死亡陷阱可以避免。 – 2013-02-28 13:49:29

+0

@MikeSeymour,我同意。但问题是如何在这种特殊情况下避免SO。 – 2013-02-28 13:57:35

+2

确实,这是个问题。在我看来,最好的答案是重新设计班级,以免造成SO,而不是要求班级的用户以非常规方式使用它。 – 2013-02-28 14:00:53

3

即使您的int是2字节的最小大小,您的数组也会使用大约86MB的内存。典型的最大堆栈大小为1MB。如果您的Test对象的存储已分配到堆栈上,则很容易溢出。您需要动态分配数组,或者不要一次将所有数据全部加载到内存中。更好的是,使用一个标准容器,为其元素使用动态分配,比如`std :: vector。

3

此声明在类:

int myarray[45000000]; 

试图分配每个INT 45000000 * 4个字节(假定32位)=的存储器180MB。没有办法你的堆栈将支持。您需要重新设计应用程序以更改加载文件的方式。

相关问题