为什么我的程序在构造函数中使用read时会崩溃?

Why does my program crash when using fread in the constructor?

本文关键字:read 崩溃 程序 我的 构造函数 为什么      更新时间:2023-10-16

我有一个用c++编写的小程序,其中包含一个带有大数组的类。该类看起来像这样:

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 Ultimate:当尝试启动使用该类的程序时,一旦创建类,它就会以"APPCRASH"崩溃,并且当尝试调试它时(我几乎不知道),告诉我错误是堆栈溢出。

这一切的神秘之处在于,在我之前的版本中,myarray是一个静态变量,我必须调用一个静态函数来设置它,一切都很好。但是,当我试图将它转换为构造函数时,我所做的一切尝试都失败了。

我哪里做错了?

即使您的int的最小大小为2字节,您的数组也将使用大约86MB的内存。典型的最大堆栈大小为1MB。如果Test对象的存储是在堆栈上分配的,那么很容易溢出。你需要动态地分配你的数组,或者不把所有的数组一次加载到内存中。更好的方法是使用动态分配元素的标准容器,如std::vector.

所以您应该在主程序(或其他任何地方)

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

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

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

使用静态变量不会崩溃,因为静态变量不是在堆栈上分配的

类中的声明:

int myarray[45000000];

试图为每个int(假设为32位)分配45,000,000 * 4字节= 180MB内存。你的堆栈不可能支持这个。你需要重新设计应用程序来改变加载文件的方式。