使用 i/o 流的分段错误

Segmentation fault using i/o stream

我正在尝试解决一个高中问题,但出现分段错误 当我尝试调试我的程序时。你能告诉我我的代码有什么问题吗?

#include <iostream>
#include <stdlib.h>
#include <fstream>

using namespace std;

ifstream fin;
ofstream fout;

void afisare_cifre(int a[30],int n)
{
 int nr=0,cp;
 for(int i=0;i<n;i++)
 {
    cp=a[i];
    while(cp!=0)
    {
       if((cp%10)%2==0)
         nr++;
       cp/=10;
    }
    fout<<nr<<" ";
    nr=0;
 }
    fout<<"\n";
 }

  int main ()
 {

   fin.open("in.txt", ios::in);
   fout.open("out.txt", ios::out);
   int n,p,k,a[30],ok=0;

   if(fin.bad())
   {
    cerr<<"Eroare!"<<endl;
    exit(1);
   }
  if(fout.bad())
  {
    cerr<<"Eroare!"<<endl;
    exit(1);
  }
    fin>>n>>p>>k;
    n = std::max(0,std::min(n, 30));
  for(int i=0;i<n;i++)
     fin>>a[i];

  for(int i=0;i<n;i++)
    if(a[i] % p == k)
       fout<<a[i]<<" ";

 fout<<"\n";
 afisare_cifre(a,n);

 for(int i=0;i<n;i++)
   for(int j=i+1;j<n;j++)
      if(a[i]==a[j])
          ok=1;
  if(ok)
    fout<<"ELEMENTELE NU SUNT DISTINCTE";
  else
    fout<<"ELEMENTELE SUNT DISTINCTE";

 return 0;
}

我以为可能是内存问题,没想到out.Thanks提前想通了!

您的代码的主要问题在于,您编写代码时假设数组从索引 1 而不是 0 开始,并且您的循环没有正确地将自己限制为 [=17= 的最高索引 (99) ]数组。

为了解决第二个问题,您的输入使用了一个变量 n,但是没有什么可以阻止任何人输入 n 的完全越界的值。您可以通过允许输入任何值来停止此操作,但要限制循环次数:

#include <algorithm>
//...
f_in >> n >> p >> k;
n = std::max(0,std::min(n, 100));

以上确保 n 至少为 0,但不超过 100。

接下来,将循环更改为从 0 开始。我知道其他人可能不同意编写基于 1 的数组循环是可以的,但根据我的经验,我还没有看到(新手)编码人员编写出无错误的代码尝试从 1 开始的数组访问。通常代码某处会出现"off-by-1"错误,而且这些错误很难发现。如果编码器不一致并在大型程序的某处引入基于 0 的索引,与程序中其他地方使用的基于 1 的索引冲突,则尤其如此。

因此,例如,而不是像这样的事情(由于越界访问将无法工作):

for (int i = 1; i <= n; i++)
    f_in >> a[i];

这样做:

for (int i = 0; i < n; i++)
    f_in >> a[i];

进行这些更改可能 解决您的分段错误。我没有查看您的所有代码,但这些都是明显的问题。

另外,通过使用调试器或使用 cout 在使用输入值之前显示输入值,确保您使用的是正确的值。您的代码中有这样一行:

    if (a[i] % p == k)

如果p为0,则对0取模未定义。

另一个可能的问题与流相关。您将全局变量作为流,因此您应该尝试以不同方式管理它们,看看是否可以缓解您遇到的分段错误问题。

首先是这个:

ifstream fin("Atestat.in", ios::in);
ofstream fout("Atestat.out", ios::out);

应该是:

ifstream fin;
ofstream fout;

main 里面,打开那里的文件:

f_in.open("Atestat.in", ios::in);
f_out.open("Atestat.out", ios::out);

如果在 main() returns 时发生分段错误,则这是流关闭的问题(由于调用了流对象的析构函数,这是自动的)。这不应该发生,但如果这不能纠正分段错误,您应该注意一些事情。