使用i / o流进行分段故障

时间:2015-02-06 14:54:03

标签: c++ segmentation-fault

我正在努力解决高中问题而且我遇到了分段错误 当我尝试调试我的程序时。你能告诉我我的代码有什么问题吗?

#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;
}

我认为这可能是一个记忆问题,但我无法弄明白。提前谢谢!

1 个答案:

答案 0 :(得分:1)

您的代码的主要问题是您编写代码时假设数组从索引1而不是0开始,并且您的循环没有正确地将自己限制为a数组的最高索引(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()返回时发生分段错误,那么关闭流是一个问题(由于调用了流对象的析构函数,这是自动的)。这不应该发生,但如果这不能解决分段错误,您应该注意这一点。