c++ - SIGSEGV 背后的推理?
问题描述
我正在尝试解决 SPOJ 上的“Prime Generator”问题。最初,我使用了埃拉托色尼筛法,但这需要很长时间。因此,我实施了分段筛。我的代码在我的机器上运行良好,但是当我将它提交给 SPOJ 时,我收到消息“运行时错误 (SIGSEGV)”。
谷歌搜索告诉我 SIGSEGV 与无效的内存引用或使用过多的内存有关。我是竞争性编程的新手,看不到我哪里出错了。
如果有帮助,我正在使用 CPP14-CLANG 语言。
这是代码:
#include <iostream>
#include <string.h>
#include <math.h>
#include <vector>
#include <sstream>
int main(){
int nt=0, l_value=0, r_value=0, v=1;
int lr_array[20] = {0};
std::vector <int> soe;
std::vector <std::string> token;
std::vector <int> prime_list(1e5, 1);
//take number of test cases and their respective range
std::cin>>nt;
std::cin.ignore();
for(int i=0;i<nt;i++)
{
std::string line;
getline(std::cin, line);
std::stringstream check1(line);
std::string intermediate;
while(getline(check1, intermediate, ' '))
{
token.push_back(intermediate);
}
for(int i=0;i<token.size();i++)
{
lr_array[i] = std::stoi(token[i]);
}
}
//Find out primes till sqrt(y) by using Sieve of Erathosthenes
for(int i=0;i<=32000;i++)
{
soe.push_back(1);
}
for(int k=2;k<32000;k++)
{
if(soe[k])
{
for(int j=(k*k);j<=32000;j+=k)
{
soe[j] = 0;
}
}
}
//Use each element from SoE list to determine non-primes in given range
for(int i=0;i<nt;i++)
{
for(int j=2;j<soe.size();j++)
{
if(soe[j] && (j<=lr_array[i+v]))
{
int temp = int((lr_array[2*i]/j));
temp = temp*j;
if(temp<lr_array[2*i]){
temp += j;
}
for(int k=lr_array[2*i];k<=lr_array[i+v];k++)
{
if(k==lr_array[2*i])
{
if(j==2){prime_list[temp]=0;continue;}
else{temp+=j;prime_list[temp]=0;continue;}
}
if(temp<=lr_array[i+v])
{
prime_list[temp]=0;
temp += j;
}
else{
break;
}
}
}
}
if(lr_array[2*i]<=2){prime_list[2]=1;}
for(int l=lr_array[2*i];l<=lr_array[i+v];l++){
if(prime_list[l]==1)
{
std::cout<<l<<std::endl;
}
}
v++;
std::cout<<std::endl;
}
return 0;
}
我也提到了这个StackOverflow 问题,但它没有帮助。
解决方案
当代码尝试访问未分配的内存部分时,会发生分段错误。如果你不够幸运,你可能会发现你的代码执行得“很好”。那就是发生内存损坏的时候。该进程写入一块已通过更改分配但不属于感兴趣的数组的内存块。
在您的内部循环中,您尝试访问soe
的内存远远超过分配的内存。它落在外面(如果你幸运的话)或破坏其他变量(如果你不走运)
for(int k=2;k<32000;k++)
{
if(soe[k])
{
for(int j=(k*k);j<=32000;j+=k)
// j grows up to 32000. Largesr valid index for soe is 31999
{
soe[j] = 0; // <====== This is where segfault happens
}
}
}
推荐阅读
- python - Pyplot:在右侧以相同的比例添加特定的附加刻度和标签
- json - Postgres 为每个查询创建一个 JSON 对象
- rpm - RPM Spec 文件将 tar.gz 解压到多个位置
- vue.js - 以编程方式将焦点设置在 Vuetify 中的按钮上
- nginx - 如何在 nginx 中使用 proxy_pass 保留 url 端口
- css - 样式化的组件样式应该放在组件树的什么位置?
- javascript - Generate HTML from file fetched from server
- html - Push next DIV down when content overlap in position relative / absolute
- c# - 调用时访问中间件选项
- visual-studio - What is the number next to the opened file name in visual studio?