【问题标题】:Why am I getting a 'Runtime Error - SIGSEGV' in my code?为什么我的代码中出现“运行时错误 - SIGSEGV”?
【发布时间】:2019-08-12 13:34:51
【问题描述】:

我有一些不可能的问题要问你! (还是他们?;))

您有长度为m 的二进制数nith 二进制数是 Bi。此外,您必须对它们执行q 查询。索引从零开始,位的索引从左开始。

查询的类型为:aij
如果a 是:

  • 0 : Bi 和 Bj 进行逻辑与运算,并在结果中输出1s 的个数。
  • 1 : Bi 和 Bj 进行逻辑或运算,并在结果中输出1s 的个数。
  • 2 : Bi 和 Bj 进行逻辑异或运算,并在结果中输出1s 的个数。
  • 3 :翻转 Bijth 位的值(即,如果等于 1,则将该位设置为 0,反之亦然)。

注意:对于012类型的查询,二进制数保持不变。

C++ 和 JAVA 程序员也建议使用 Fast I/O。


输入格式:

第一行包含整数 nm
接下来的n 行包含长度为m 的二进制数。
ith 行包含二进制数 Bi
下一行包含一个整数q
接下来的q 行包含以下类型的查询:aij

输出格式:

012 类型查询的结果中的 1s 的输出数量。

约束:
1<=n, m<=2500
1<=q<=10^6

我已尝试更改数组大小,但错误仍然相同!

#include <iostream>
#include <math.h>
#include <bits/stdc++.h>
using namespace std;


int main() 
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int n,m;
    cin>>n>>m;
    char arr[3000][3000];

    for(int i=0;i<n;i++)
    for(int j=0;j<m;j++)
    {
        cin>>arr[i][j];
    }


    long int q;
    cin>>q;
    char query[3000][3000];
    for(long int k=0;k<q;k++)
    for(long int l=0;l<3;l++)
    {
        cin>>query[k][l];
    }


    for(long int i=0;i<q;i++)
    {
        if(int(query[i][0]-48)==3)
        {
            if(arr[int(query[i][1])-48][int(query[i][2])-48]=='1')
            {
                arr[int(query[i][1])-48][int(query[i][2])-48]='0';
            }
            else
            {
                arr[int(query[i][1])-48][int(query[i][2])-48]='1';
            }
        } 

        else if(int(query[i][0]-48)==2)
        {
            int cntr=0;
            int bi=int(query[i][1])-48;
            int bj=int(query[i][2])-48;

            for(int i=0;i<m;i++)
            {
                int xorres=arr[bi][i]^arr[bj][i];
                if(xorres==1)
                cntr++;
            }
            cout<<cntr<<endl;
        }

        else if(int(query[i][0]-48)==1)
        {
            int cntr=0;
            int bi=int(query[i][1])-48;
            int bj=int(query[i][2])-48;

            for(int i=0;i<m;i++)
            {
                int andres=arr[bi][i]|arr[bj][i];
                if(andres-48==1)
                cntr++;
            }
            cout<<cntr<<endl;

        }

        else if(int(query[i][0]-48)==0)
        {
            int cntr=0;
            int bi=int(query[i][1])-48;
            int bj=int(query[i][2])-48;

            for(int i=0;i<m;i++)
            {
                int andres=arr[bi][i]&arr[bj][i];
                if(andres-48==1)
                cntr++;
            }
            cout<<cntr<<endl;

        }
    }



    return 0;
}

【问题讨论】:

  • 局部变量(包括数组)由编译器放置在堆栈上。堆栈是有限的资源,例如Linux 它是 8MiB。现在想想数组arr...它需要多少空间? arr query 一起需要多少空间?是时候了解std::vector了。还有get a few good books。在线评委/竞赛网站对初学者来说真的很糟糕。
  • 您不需要在处理之前存储所有查询。一次做一个。使用向量的向量作为输入。 (或者静态数组,如果你绝对必须使用数组。)
  • 另外,'0' 既便携又易于理解; 48 不是。

标签: c++ arrays segmentation-fault runtime


【解决方案1】:

您在堆栈上分配的两个char[3000][3000]崩溃的原因。

由于n 没有上限限制,您最好尝试在堆上分配它并在失败时捕获异常。这可以通过使用std::vector&lt;std::vector&lt;char&gt;&gt; 来完成。

替换:

int n,m;
cin >> n >> m;
char arr[3000][3000];

这样的:

#include <vector>

size_t n, m;
std::vector<std::vector<char>> arr;

while(std::cin >> n >> m) {
    try {
        arr.resize(n, std::vector<char>(m));
        break; // success, break out of the while-loop
    } catch(const std::exception& ex) {
        // exception caught, most probably a bad_alloc
        std::cerr << ex.what() << " ... try again\n";
    }
}

按照 cmets 中的建议,您可能不需要存储所有查询。一次只处理一个查询。

另外,永远不要#include &lt;bits/stdc++.h&gt;自己。这是一个非标准/不可移植的头文件,包含很多超出您的需要,而且通常不是您需要的全部。相反,只包含您实际需要的标题。

同样,using namespace std;considered bad practice

【讨论】:

    【解决方案2】:

    好的,所以我认为你在这里把一些事情复杂化了。 查询的大小为 10^6,您将数组声明为 query[3000][3000]。 现在,我认为您不需要存储查询。考虑一下-

    cin>>q;
    while(q--)
    {
        cin>>a>>i>>j;
        /*Your code here*/
    }
    

    问题表明查询的形式为:a i j 因此,例如,如果您想对前 2 个字符串执行操作 0,则查询将是: 0 1 2 但是您正在存储索引 0 中的二进制数! 因此,您的代码将对第二个和第三个查询执行操作。所以,你需要做的就是从 i 和 j 的值中减去 1。

    【讨论】:

      猜你喜欢
      • 2015-12-13
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-25
      • 2020-12-15
      • 1970-01-01
      相关资源
      最近更新 更多