2016-03-11 86 views
-1

我是mmap新手,仍然在學習它。根據我的理解,我已經創建了mmap類,它將用於映射內存中的文件。整個班級工作正常,但問題是當析構函數被調用時..問題是分段錯誤或無效指針錯誤是在主函數的末尾...我已經發布了我的類和主函數的代碼正在使用類...mmap錯誤:分段錯誤/無效指針錯誤

Map.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; 

}; 

MapData.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]='\0'; 
     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 "); 
} 

Main.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]='\0'; 

        // 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] 
+0

編輯......此類我要去通過映射內存中的文件進行快速訪問用於文件處理... – macmore

+0

請考慮增加調試輸出(如'printf's)熬下來到代碼中更具體的部分,這可能有助於確定問題。如果所有在那裏完成的都是'printf(「Inside MADATA Destructor \ n」);那麼析構函數應該是什麼問題? –

+0

我試着用各種可能的方式使用gdb進行調試...程序得到執行正常,但在刪除調用Mmap指針析構函數被調用和程序停止..我在這裏張貼由gdb生成的堆棧跟蹤....... – macmore

回答

-1

可能是在這裏。

char ptrFileNm[250+1]; 
char acFileNm[500+1]; 

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

我檢查了文件名變量沒有問題...問題是執行Mmap的析構函數.... – macmore