2016-03-11 7 views
-1

Я новичок в mmap и все еще изучаю его. Основываясь на моем понимании, я создал класс для mmap, который будет использоваться для сопоставления файла в памяти. Весь класс работает нормально, но проблема возникает, когда вызывается деструктор. Проблема связана с ошибкой сегментации или неправильной ошибкой указателя в конце основной функции ... Я опубликовал код моего класса и основной функции, которая использует этот класс ...mmap error: segmentation fault/invalid pointer error

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

Edited ... Этот класс я буду использовать для обработки файлов путем отображения файла в памяти для быстрого доступа к ... – 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