mmap 错误:分段错误/指针无效错误

mmap error : segmentation fault/invalid pointer error

本文关键字:错误 指针 无效 分段 mmap      更新时间:2023-10-16

我是mmap的新手,还在学习它。根据我的理解,我已经为 mmap 创建了类,该类将用于映射内存中的文件。整个类工作正常,但是当调用析构函数时出现问题。问题是分段错误或无效指针错误出现在 main 函数的末尾......我已经发布了我的类和使用该类的主函数的代码......

地图.h

class MapData   
{
     public :
            MapData();
            ~MapData();
            MapData(char []);
            bool OPEN();    
            void fnClose();
            long fnGetSize();
            char * fnGetFileRef();
            char * ReadNextData(int );
private :
            char * ptrRecord;
            char  ptrFileNm[250+1];
            int fd;
            struct stat sbuf;
            bool bSuccess;
            long sTotalSize;
            char acData[2000+1];
            long lCurrRead;
};

地图数据.cpp

MapData::MapData()
{
}
MapData::~MapData()
{
   printf("Inside MADATA Destructor n ");
}
MapData::MapData(char acInput[])
{
    strcpy(ptrFileNm,acInput);
    sTotalSize=0;
    lCurrRead=0;
    bSuccess=false;
}
bool MapData::OPEN()
{
    // if failed return false flg
    if ((fd = open(ptrFileNm, O_RDONLY)) == -1) {
    return bSuccess;
    }
    if (stat(ptrFileNm, &sbuf) == -1) {
       return bSuccess;
    }
    // copy in local variable
    sTotalSize = sbuf.st_size;
    ptrRecord = (char * )mmap( (caddr_t)0, sTotalSize, PROT_READ, MAP_SHARED, fd, 0) ;
    if (ptrRecord == (char *)(caddr_t)(-1) ) {
       perror("Fail to Map Data ");
       return bSuccess;
    }
    else
    {
       printf("Successfully Map Data***[%ld] n",sTotalSize);
       bSuccess=true;
    }
    return bSuccess;
}
char * MapData::fnGetFileRef()
{
    return ptrRecord;
}
char * MapData::ReadNextData(int iX)
{
    if((lCurrRead+iX)<sTotalSize)
    {
        memset(acData,0x00,sizeof(acData));
        strncpy(acData,ptrRecord+lCurrRead,iX);
        acData[iX+1]='';
        lCurrRead+=iX;
    }else{
        strcpy(acData,"ZZZ");
    }
    return acData;
}
long MapData::fnGetSize()
{
    return sTotalSize;
}
void MapData::fnClose()
{
     // Don't forget to free the mmapped memory
     if(munmap(ptrRecord, sTotalSize) == -1)
     {
         close(fd);
         perror("Error un-mmapping the file");
         exit(EXIT_FAILURE);
     }
     // Un-mmaping doesn't close the file, so we still need to do that.
     close(fd);
     printf("CLOSED SUCCESSFULLY n ");
}

主.cpp

int main()
{
    char acFileNm[500+1];
    MEMSET(acFileNm);           // clean the variable
    // file name to be read 
    strcpy(acFileNm,"ABDFILE.txt");
    long lProcCnt=0;                    // no of byte read by program
    char acLine[MAX_LINE_LENGTH+1]; // hold current read line
    bool bFlag=true;        // main flag 
    DEBUG_PRINT("File to be processed:%s n",acFileNm);
    // create object of mmap
    MapData * pt1 = NULL;
    pt1 = new MapData(acFileNm);
    if(!pt1)
    {
        cout<<"Error creating object so quit ..."<<endl;
        return 0 ;
    }
    auto_ptr<MapData> ptrMap( pt1 );                    // pass ownership to auto deletor to delete memory

    DEBUG_PRINT("STEP1:%s n","OBJECT CREATION FOR FILE MAPPED IN MEMORY");

    // try to open the file 
    if(ptrMap->OPEN())
    {
            // on success..get pointer to first char of file
            char * ptrData = ptrMap->fnGetFileRef();
            long lCompSize=ptrMap->fnGetSize();     // total no of bytes = fiexed line size * no of row + (no of row * EOL)

            short int iEOL=0;
            // logic to identify file generated on ewhich OS
            if( (*(ptrData+MAX_LINE_LENGTH) == 'r') && (*(ptrData+MAX_LINE_LENGTH+1) == 'n'))
            {
                    // DOS format CRLF
                    iEOL = 2;
            }else if(*(ptrData+MAX_LINE_LENGTH) == 'n'){
                    // Unix format LF
                    iEOL = 1;
            }
            DEBUG_PRINT("STEP2: SIZEOFFILE%ld FILESYSTEM FORMAT:%d n",lCompSize,iEOL);

            // here read till it reaches maximum limit of file
            while(lProcCnt<lCompSize)
            {
                    //DEBUG_PRINT("PROC COUNTER[%ld] MAX_COUNTER[%ld] n",lProcCnt,lCompSize);
                    lProcCnt+=MAX_LINE_LENGTH+iEOL;             // increement no of bytes read at initial
                    MEMSET(acLine);
                    strncpy(acLine,ptrData+lProcCnt,MAX_LINE_LENGTH);       // read line
                    acLine[MAX_LINE_LENGTH+1]='';
                    // process the line  :function is called here to process the line
            }
    }else{
            DEBUG_PRINT("MAP DATA FAILED OF FILE[%s] n",acFileNm);
            bFlag=false;
    }
    // at the end check if all the controls are matched 
    if(bFlag)
    DEBUG_PRINT("END OF FILE PROCESSING SUCCESS n");
    else        
    DEBUG_PRINT("END OF FILE PROCESSING FAILED n");

    // close the memory map
    ptrMap->fnClose();
    MapData * ptr5 = ptrMap.release();      // release the ownership 
    delete ptr5;   **// segmentation fault comes here ...**
}

请告诉我哪里出了问题,因为 gdb 也没有帮助......详细的解释对我理解有好处...

Stacktrace generated by gdb:
*** glibc detected *** DemoMap: free(): invalid pointer: 0x0804c000 ***
======= Backtrace: =========
/lib/libc.so.6[0x9bbc81]
/lib/libc.so.6[0x9be562]
/usr/lib/libstdc++.so.6(_ZdlPv+0x22)[0x544552]
DemoMap[0x80491e6]
/lib/libc.so.6(__libc_start_main+0xe6)[0x961d36]
DemoMap[0x8048d91]
======= Memory map: ========
00110000-00111000 r-xp 00000000 00:00 0          [vdso]
0044c000-00469000 r-xp 00000000 08:03 1237       /lib/libgcc_s-4.4.7-20120601.so.1
00469000-0046a000 rw-p 0001d000 08:03 1237       /lib/libgcc_s-4.4.7-20120601.so.1
00495000-00576000 r-xp 00000000 08:02 132841     /usr/lib/libstdc++.so.6.0.13
00576000-0057a000 r--p 000e0000 08:02 132841     /usr/lib/libstdc++.so.6.0.13
0057a000-0057c000 rw-p 000e4000 08:02 132841     /usr/lib/libstdc++.so.6.0.13
0057c000-00582000 rw-p 00000000 00:00 0 
00929000-00947000 r-xp 00000000 08:03 1065       /lib/ld-2.12.so
00947000-00948000 r--p 0001d000 08:03 1065       /lib/ld-2.12.so
00948000-00949000 rw-p 0001e000 08:03 1065       /lib/ld-2.12.so
0094b000-00adb000 r-xp 00000000 08:03 1067       /lib/libc-2.12.so
00adb000-00adc000 ---p 00190000 08:03 1067       /lib/libc-2.12.so
00adc000-00ade000 r--p 00190000 08:03 1067       /lib/libc-2.12.so
00ade000-00adf000 rw-p 00192000 08:03 1067       /lib/libc-2.12.so
00adf000-00ae2000 rw-p 00000000 00:00 0 
00b29000-00b51000 r-xp 00000000 08:03 1211       /lib/libm-2.12.so
00b51000-00b52000 r--p 00027000 08:03 1211       /lib/libm-2.12.so
00b52000-00b53000 rw-p 00028000 08:03 1211       /lib/libm-2.12.so
08048000-0804b000 r-xp 00000000 08:08 2883976    DemoMap
0804b000-0804c000 rw-p 00002000 08:08 2883976    DemoMap
0804c000-0806d000 rw-p 00000000 00:00 0          [heap]
b7e00000-b7e21000 rw-p 00000000 00:00 0 
b7e21000-b7f00000 ---p 00000000 00:00 0 
b7f9b000-b7fe5000 r--s 00000000 08:08 4326707    ABCDEF.TXT
b7fe5000-b7fe8000 rw-p 00000000 00:00 0 
b7ffd000-b8000000 rw-p 00000000 00:00 0 
bffeb000-c0000000 rw-p 00000000 00:00 0          [stack]

可能在这里。

char  ptrFileNm[250+1];
char acFileNm[500+1];
MapData::MapData(char acInput[])
{
    strcpy(ptrFileNm,acInput);//segmentation fault 
    sTotalSize=0;
    lCurrRead=0;
    bSuccess=false;
}