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

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 微信小程序跑脚本授权的问题
  • ¥100 房产抖音小程序苹果搜不到安卓可以付费悬赏
  • ¥15 STM32串口接收问题
  • ¥15 腾讯IOA系统怎么在文件夹里修改办公网络的连接
  • ¥15 filenotfounderror:文件是存在的,权限也给了,但还一直报错
  • ¥15 MATLAB和mosek的求解问题
  • ¥20 修改中兴光猫sn的时候提示失败
  • ¥15 java大作业爬取网页
  • ¥15 怎么获取欧易的btc永续合约和交割合约的5m级的历史数据用来回测套利策略?
  • ¥15 有没有办法利用libusb读取usb设备数据