【问题标题】:What could be the reason I am getting segmentation fault using code 1?使用代码 1 出现分段错误的原因可能是什么?
【发布时间】:2019-10-23 21:05:24
【问题描述】:

埃拉托色尼筛法: 当我使用代码 1 过滤素数时,我得到输入 16777214 的分段错误,而在代码 2 中它没有给出分段错误。分段错误是由于我定义 (bool prime) 和 (memset) 的前 2 行代码 1 造成的。我在https://www.interviewbit.com/problems/prime-sum/ 上遇到此错误的原因可能是什么

//code 1:
vector<int> Solution::primesum(int A){
    bool prime[A+1];
    memset(prime, true, sizeof(prime));
    for (int p=2;p<=sqrt(A);p++){
        if(prime[p] == true){
            for (int i=p*p;i<=A;i+=p)
                prime[i] = false;
        }
    }
}
````
````

//code 2:
vector<int> Solution::primesum(int A){
    vector<bool> prime(A+1);
        for(int i=2;i<=sqrt(A);i++){
            if(prime[i]==false){
                for(int j=i*i;j<=A;j+=i)
                    prime[j] = true;
            }
        }
}
````
````

【问题讨论】:

  • 变量“n”的数据类型是什么?
  • 抱歉,我将变量“n”更改为“A”,两种情况下的数据类型都是 int。
  • 通过访问未初始化的变量A,两个片段都表现出未定义的行为。唯一的区别是这种未定义行为的表现方式。
  • 你不能这样初始化数组
  • 您的memset 不是设置布尔数组的有效方法。

标签: c++


【解决方案1】:

假设变量A是在创建数组之前初始化的,数组的内存是在栈上分配的,由于栈的大小是有限的,分配内存为16777214字节会导致栈溢出,从而导致分段故障。

另一方面,向量是在堆上分配的,不会发生同样的问题。

P.S:可变长度数组不是标准 C++,GCC 将它们作为非标准扩展来实现。

【讨论】:

  • 这不是因为 bool 向量是节省空间的。这是因为向量将它们的元素分配在堆上,而不是堆栈上。您还应该提到 VLA 不是标准 C++。
【解决方案2】:

当任一数组超出索引并且您正在访问非法内存空间时,会发生分段错误。

首先,数组不能以这种方式动态初始化。你应该试试这个方法,

int *prime = new int[length];

其次,也许是为了你,prime[n+1], 您的输入值超出了 "n" (int) 的限制。当您使用数据类型 int 时,它有内存限制。尝试使用long int

【讨论】:

  • 数组初始化正确。这两个代码都适用于较低的输入。我将变量“n”更改为“A”。另外,我明确要求输入 16777214。
猜你喜欢
  • 2021-04-09
  • 1970-01-01
  • 1970-01-01
  • 2012-03-16
  • 2013-06-16
  • 2022-11-18
  • 2011-01-19
  • 2021-02-28
  • 1970-01-01
相关资源
最近更新 更多