【问题标题】:Runtime Error(SIGSEGV) in codechefcodechef 中的运行时错误(SIGSEGV)
【发布时间】:2015-08-17 12:59:41
【问题描述】:

我正在解决一个问题https://www.codechef.com/problems/DCGAME/ 在这里面,我找不到运行时错误(SIGSEGV)背后的原因。在我的电脑上,输出很好。我知道这个错误的含义,但仍然无法找到我在哪里犯了错误。我的代码如下:

  #include <stdio.h>
  void calc(long long int arr1[],int n,long long int arr2[][n],long long int  game[],int m)
  {
 //printf("Pre process %d %d",n,m);
 int i,j;
 for(i=0;i<n;i++){game[arr1[i]]++;}
 for(i=1;i<n;i++)
 {
       for(j=0;j<=n-i-1;j++)
       {
           if(arr2[i-1][j]>arr1[i+j])
           arr2[i][j]=arr2[i-1][j];
           else
           arr2[i][j]=arr1[i+j];
           game[arr2[i][j]]++;
       }
   }
//for(i=0;i<=m;i++){printf(" %d ",game[i]);}
 }
  int main(){

  int n,m,i,count=0,k;
  char c,p;
  scanf("%d %d",&n,&m);
  long long int a[n],b[n][n],max=0;

  for(i=0;i<n;i++)
  {
   scanf("%lld",&a[i]);
   if(a[i]>max)max=a[i];
   b[0][i]=a[i];
  }
   long long int game[max+1];
   for(i=0;i<=max;i++)
   game[i]=0;
   calc(a,n,b,game,max);
   while(m--)
  {
   // printf("WHILE-M");
   c=getchar();

   //scanf("%c",&c);
    scanf("%c %d %c",&c,&k,&p);

        switch(c)
        {//printf("SWITCH");
            case '<':
            //printf("CASE <");
            if(k>max){if(p=='D')
                {
                    printf("C");count=0;
                }
                else
                {
                    printf("D");count=0;
                }break;}
            for(i=1;i<k;i++)
            {if(game[i]>0)
            count+=game[i];
            }
            if(count%2==0)
            {
                if(p=='D')
                {
                    printf("C");count=0;
                }
                else
                {
                    printf("D");count=0;
                }
            }
            else
            {
                if(p=='D')
                {
                    printf("D");count=0;
                }
                else
                {
                    printf("C");count=0;
                }
            }
            break;
            case '>':
            //printf("CASE >");
            if(k>max){if(p=='D')
                {
                    printf("C");count=0;
                }
                else
                {
                    printf("D");count=0;
                }break;}
            for(i=k+1;i<=max;i++)
            {if(game[i]>0)
            count+=game[i];
            }
            if(count%2==0)
            {
                if(p=='D')
                {
                    printf("C");count=0;
                }
                else
                {
                    printf("D");count=0;
                }
            }
            else
            {
                if(p=='D')
                {
                    printf("D");count=0;
                }
                else
                {
                    printf("C");count=0;
                }
            }
            break;

            case '=':
            //printf("CASE =");
            if(k>max){if(p=='D')
                {
                    printf("C");count=0;
                }
                else
                {
                    printf("D");count=0;
                }break;}
            count+=game[k];
            if(count%2==0)
            {
                if(p=='D')
                {
                    printf("C");count=0;
                }
                else
                {
                    printf("D");count=0;
                }
            }
            else
            {
                if(p=='D')
                {
                    printf("D");count=0;
                }
                else
                {
                    printf("C");count=0;
                }
            }
            break;
        }


      }
      return 0;

     }

【问题讨论】:

  • 你知道n 的输入可以有多大吗?您在堆栈上分配这些数组,如果 n 很大,像 b 这样的矩阵很容易变得比可用堆栈大。
  • @JoachimPileborg 我很感激你的回答。如果你建议我一些好的替代方案会非常有帮助
  • @ameyCU 声明 c=getchar();只是为了避免 \n(newline) 字符作为输入,因为我的输入是逐行的,因此每个输入后面都跟着换行符。字符变量也是一种整数,所以不会引起任何问题:)
  • 问题约束指定n可以达到10^6,也就是说二维数组b[n][n]肯定会导致栈溢出。

标签: c segmentation-fault


【解决方案1】:

如果您的算法在其他方面是正确的(我没有检查)但您的堆栈空间不足,那么一个简短的解决方法是将 long long int a[n],b[n][n],max=0; 更改为:

long long int *a, (*b)[n], max = 0;
a = malloc(n * sizeof *a);
b = malloc(n * sizeof *b);

并将long long int game[max+1]; for(i=0;i&lt;=max;i++) game[i]=0; 更改为:

long long int *game = calloc(max+1, sizeof *game);

您还应该检查失败,例如if ( !a || !b ) exit(EXIT_FAILURE);。其余代码可以保持不变。

【讨论】:

  • @Quentin 好吧,OP 正在做一个定时挑战,所以free() 会无缘无故减慢程序。在这种情况下,操作系统会在进程退出时释放进程分配的所有内存。
  • 我怀疑对free 的三个调用会改变什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多