当读取超过500000个整数时,c++程序无法执行

c++ program unable to execute while reading more than 500000 integers

本文关键字:程序 c++ 执行 读取 500000个 整数      更新时间:2023-10-16

我有一个项目,我必须在其中存储一些值,并根据它们返回一些结果。结果和存储的值都是整数。我把每个变量都做成了一个长整型,这样它就一定能适应数字(数组可能长达1000000)。虽然我在存储的多达400000个数字上获得了完全正常的值,并且我在较低的时间(0.25秒)内获得了这些值,但在500000个数字上,程序无法执行。如果我的防病毒软件打开,一旦我尝试构建或运行它,它甚至会删除可执行文件。不过,在构建时,程序本身不会显示任何语法错误。有什么想法吗?

以下代码:

#include <iostream>
#include <fstream>
using namespace std;
int main() {
  ifstream TextIn;
  ofstream TextOut;
  long long int N, i=1, sum=0;
  TextIn.open("share.in", ios::in);
  TextIn >> N;
  long long int A[N];
  for (i=1; i<=N; i++) {
    TextIn >> A[i];
    sum=sum+A[i];
  }
  TextIn.close();
  long long int sum1c2=0, sum1c1=0;
  i=0;
  do {
    i=i+1;
    sum1c1=sum1c1+A[i];
  } while ((sum1c1<=2+sum/3) && (i<N-2));
  sum1c2=sum1c1-A[i];
  long long int sum2c1c1=0, sum2c1c2=0, sum2c2c1=0, sum2c2c2=0, j=i-1;
  do {
    j=j+1;
    sum2c1c1=sum2c1c1+A[j];
  } while ((sum2c1c1<=2+sum/3) && (j<N-1));
  sum2c1c2=sum2c1c1-A[j];
  j=i;
  do {
    j=j+1;
    sum2c2c1=sum2c2c1+A[j];
  } while ((sum2c2c1<=2+sum/3) && (j<N-1));
  sum2c2c2=sum2c2c1-A[j];
  long long int sum3c1, sum3c2, sum3c3, sum3c4;
  sum3c1=sum-sum1c1-sum2c2c1;
  sum3c2=sum-sum1c1-sum2c2c2;
  sum3c3=sum-sum1c2-sum2c1c1;
  sum3c4=sum-sum1c2-sum2c1c2;
  long long int max1=0, max2=0, max3=0, max4=0;
  if (sum1c1>sum2c2c1) {
    if (sum1c1>sum3c1){
      max1=sum1c1;
    } else {
      max1=sum3c1;
    }
  } else {
    if (sum2c2c1>sum3c1) {
      max1=sum2c2c1;
    } else {
      max1=sum3c1;
    }
  }
  if (sum1c1>sum2c2c2) {
    if (sum1c1>sum3c2) {
      max2=sum1c1;
    } else {
      max2=sum3c2;
    }
  } else {
    if (sum2c2c2>sum3c2) {
      max2=sum2c2c2;
    } else {
      max2=sum3c2;
    }
  }
  if (sum1c2>sum2c1c1) {
    if (sum1c2>sum3c3) {
      max3=sum1c2;
    } else {
      max3=sum3c3;
    }
  } else {
    if (sum2c1c1>sum3c3) {
      max3=sum2c1c1;
    } else {
      max3=sum3c3;
    }
  }
  if (sum1c2>sum2c1c2) {
    if (sum1c2>sum3c4) {
      max4=sum1c2;
    } else {
      max4=sum3c4;
    }
  } else {
    if (sum2c1c2>sum3c4) {
      max4=sum2c1c2;
    } else {
      max4=sum3c4;
    }
  }
  long long int final_max;
  if (max1<=max2 && max1<=max3 && max1<=max4) {
    final_max = max1;
  } else if (max2<=max1 && max2<=max3 && max2<=max4) {
    final_max = max2;
  } else if (max3<=max1 && max3<=max2 && max3<=max4) {
    final_max = max3;
  } else {
    final_max = max4;
  }
  TextOut.open("share.out", ios::out);
  TextOut << final_max;
  TextOut.close();
  return 0;
}    

如果不使用编译器扩展,就无法在堆栈上声明具有运行时大小的数组。所以long long int A[N];是非法的。

也就是说,对于一个500000元素的数组,您很可能会遇到堆栈溢出。你应该做一些类似的事情

TextIn >> N;
std::vector<long long int> A(N);
for (long long int i = 1; i < N; ++i)
{
    TextIn >> A[i];
    sum += A[i];
}
TextIn.close();

这将有所帮助的原因是,即使向量A是在堆栈上声明的,底层内存也是从堆中分配的,堆的可用内存比堆栈多得多。

在C++中使用运行时值作为数组中的项数来创建数组是不合法的C++。有些编译器可以使用扩展来实现这一点,但这仍然意味着代码使用了非标准的C++语法。

为了解决这个问题,再加上很可能解决您的问题,请使用std::vector而不是数组:

TextIn >> N;
std::vector<long long int> A(N);

第二个问题是你的程序中至少有一个内存覆盖:

for (i=1;i<=N;i++)
{
    TextIn >> A[i];
    sum=sum+A[i];
}

在C++中,数组的索引从0开始,而不是从1开始,然后转到n-1,其中n是条目总数。所以上面的循环应该是:

for (i=0;i <N; i++)
{
    TextIn >> A[i];
    sum=sum+A[i];
}

如果没有看过您的代码,我会说500000个整数是一个非常大的数字。让我们假设每个整数有8个字节(我认为这是长-长的最小大小)。

500000*8==4000000字节或4兆字节,如果不是,这可能接近程序堆栈的大小。

解决方案:如果要存储那么多数据,请尝试使用堆内存。

尽管这可能不是问题所在,尤其是如果防病毒软件将其标记出来(这对我来说似乎很奇怪)。如果是这种情况,你的程序就会出错。