Maisel 2022-01-30 17:23 采纳率: 81.8%
浏览 284
已结题

C++ 出现异常"segmentation fault"

问题遇到的现象和发生背景

从上亿个IP中提取出出现次数最多的IP。

问题相关代码,请勿粘贴截图

#include <fstream>
#include <iostream>
#include <sstream>
#include <unordered_map>
#include <string>
#include <ctime>
using namespace std;
 
const unsigned N=10000000;      //随机产生的IP地址数
const unsigned FILE_NUM=16;      //产生的小文件个数
const unsigned HASH_SHIFT=28;    //散列值的位移量
 
inline unsigned HashInt(unsigned value); //将整数散列到0到FILE_NUM之间
bool ProduceIP(string fileName);                //随机产生IP地址,看成是32位无符号数
bool DecomposeFile(string fileName);     //分而治之,将大文件分为若干个小文件
bool FindTargetIP(unsigned result[2]);      //找到出现次数最多的IP
 
int main()
{
    unsigned start,end;      //记录总的运行时间
    unsigned start1,end1;  //产生大文件的时间
    unsigned start2,end2;  //分解大文件的时间
    unsigned start3,end3;  //找出现IP次数最多的时间
 
    string name="IP.bin";       //大文件
    unsigned result[2]={0,0};   //保存结果
 
    start=clock();
    start1=clock();
    //随机产生大量IP
    if(ProduceIP(name)==false)
        return 1;
    end1=clock();
 
    start2=clock();
    //分而治之
    if(DecomposeFile(name)==false)
        return 1;
    end2=clock();
 
    start3=clock();
    //找到出现次数最多的IP
    if(FindTargetIP(result)==false)
        return 1;
    end3=clock();
    end=clock();
 
    //打印结果
    cout<<"total run time : "<<(end-start)/1000.0<<endl;
    cout<<"ProduceIP() run time : "<<(end1-start1)/1000.0<<endl;
    cout<<"DecomposeFile() run time : "<<(end2-start2)/1000.0<<endl;
    cout<<"FindTargetIP() run time : "<<(end3-start3)/1000.0<<endl;
    cout<<"IP : "<<(result[0]>>24)<<'.'<<((result[0]&0x00ff0000)>>16)<<'.';
    cout<<((result[0]&0x0000ff00)>>8)<<'.'<<((result[0]&0x000000ff))<<endl;
    cout<<"appear time : "<<result[1]<<endl;
    return 0;
}
//将整数散列到0到FILE_NUM之间
inline unsigned HashInt(unsigned value)
{
    //斐波那契(Fibonacci)散列法 hash_key=(value * M) >> S;
    //value是16位整数,M = 40503 
    //value是32位整数,M = 2654435769 
    //value是64位整数,M = 11400714819323198485
    //S与桶的个数有数,如果桶的个数为16,那么S为28
    //对于32位整数,S=32-log2(桶的个数)
    return (value*2654435769)>>HASH_SHIFT; 
}
//随机产生IP地址 看成是32位无符号数
bool ProduceIP(string fileName)
{
    ofstream outFile(fileName.c_str(),ios::binary);
    if(!outFile)
    {
        cerr<<"error: unable to open output file : "<<fileName<<endl;
        return false;
    }
    srand(time(0));
    for(unsigned i=0;i<N;i++)
    {
        //产生一个大整数用来模拟IP地址
        unsigned x=((rand()%256)<<24)|((rand()%256)<<16)|((rand()%256)<<8)|(rand()%256);
        outFile.write((char*)&x,sizeof(unsigned));
    }
    return true;
}
//分而治之 将大文件分为若干个小文件
bool DecomposeFile(string fileName)
{
    ofstream outFiles[FILE_NUM];
    int i;
    for(i=0;i<FILE_NUM;i++)
    {
        //小文件的名称
        string name="tmp";
        name=name+to_string(i)+".bin";
        //打开小文件
        outFiles[i].open(name.c_str(),ios::binary);
        if(!outFiles[i])
        {
            cerr<<"error: unable to open output file :"<<name<<endl;
            return false;
        }
    }
    ifstream inFile(fileName.c_str(),ios::binary);
    while(inFile.good()) 
    {
        //散列到各个小文件中
        unsigned int value=0;
        if(inFile.read((char*)&value,sizeof(unsigned)))
        {
            outFiles[HashInt(value)].write((char*)&value,sizeof(unsigned));
        }
    }
    //关闭文件
    inFile.close();
    for(i=0;i<FILE_NUM;i++)
        outFiles[i].close();
    return true;
}
//找到出现次数最多的IP
bool FindTargetIP(unsigned result[2])
{
    result[0]=0;
    result[1]=0;
    for(int i=0;i<FILE_NUM;i++)
    {
        string name="tmp";
        name=name+to_string(i)+".bin";
        //处理每个小文件
        ifstream inFile;
        inFile.open(name.c_str(),ios::binary);
        if(!inFile)
        {
            cerr<<"error: unable to open input file :"<<name<<endl;
            return false;
        }
        //核心代码,由于STL中没有hash_map,用map来代替
        unordered_map<unsigned,unsigned> ip_count;
        while(inFile.good())
        {
            unsigned key=0;
            if(inFile.read((char*)&key,sizeof(unsigned)))
            {
                ip_count[key]++;
            }
        }
        unordered_map<unsigned,unsigned>::iterator it=ip_count.begin();
        for(;it!=ip_count.end();it++)
        {
            if(it->second>result[1])
            {
                result[0]=it->first;
                result[1]=it->second;
            }
        }
        inFile.close();
    }
    return true;
}
运行结果及报错内容

segmentation fault

我的解答思路和尝试过的方法
我想要达到的结果
  • 写回答

1条回答 默认 最新

  • cab_bage 2022-02-04 21:37
    关注

    数组越界,指针问题都有可能,报错没说哪一行吗

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 2月14日
  • 已采纳回答 2月6日
  • 创建了问题 1月30日

悬赏问题

  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)