Ошибка сегмента при инициализации массива файловых указателей - PullRequest
0 голосов
/ 21 апреля 2011

Может кто-нибудь, пожалуйста, помогите мне с кодом ниже. Я пытаюсь создать несколько указателей [указатель массива], чтобы каждый указывал на новую строку в моем файле. Ниже приведен код, он отлично работает в течение 4 итераций чтения первого слова из моего файла (т.е. первые четыре строки прочитаны правильно), а затем выдает ошибку:

int main () {

    int num_row = 5;
    string line="";
    long len=0;
    unsigned long *Bpos = (unsigned long *)malloc(sizeof(unsigned long)*num_row);
    int i = 0;

    //get the byte position for each of the row
     ifstream infile("out.txt");
     Bpos[i++]=0;
     while(getline(infile, line) ){
            len = strlen(line.c_str());
            Bpos[i++] = len+1;
            cout << i-1 << ": ";
            cout << Bpos[i-1] << ": " ;
            cout << line << endl;
    }

     char re[1000];// = char(*)malloc(sizeof([100];
    FILE * pFile;
    pFile = fopen("out.txt", "r");
    FILE ** fRowPtr = (FILE **)malloc(sizeof(FILE *)*num_row*20);
    int rowInd = 0;
    long byteNum =0;

//open and initialize the row pointers
for(rowInd=1; rowInd < num_row; rowInd++)
{
   fRowPtr[rowInd] = fopen("out.txt", "r"); 
   if(fRowPtr[rowInd]!=NULL)
   { 
      fseek ( fRowPtr[rowInd] ,byteNum , SEEK_SET );
      byteNum += Bpos[rowInd];
      fgets(re,20,fRowPtr[rowInd]);
      cout << "word read : " << atof(re) << endl;
    }

 }
 return 0;

}

Я делаю небольшие изменения в cout для readword, и ошибка чередуется между munmap_chunk() или ошибкой сегмента.

*** glibc detected *** ./i: munmap_chunk(): invalid pointer: 0x09f5f020 ***
======= Backtrace: =========
/lib/libc.so.6(cfree+0x188)[0x179b18]
/lib/libc.so.6(fclose+0x136)[0x167c96]
/usr/lib/libstdc++.

Результаты Valgrind


--19892-- Reading syms from /lib/libm-2.5.so (0xd6e000)
--19892-- Reading syms from /lib/libgcc_s-4.1.2-20080825.so.1 (0x911000)
--19892--    object doesn't have a symbol table
--19892-- Reading syms from /lib/libc-2.5.so (0xc14000)
--19892-- REDIR: 0xc84540 (rindex) redirected to 0x4006550 (rindex)
--19892-- REDIR: 0xc853e0 (memset) redirected to 0x4006b80 (memset)
--19892-- REDIR: 0xc841a0 (strlen) redirected to 0x4006800 (strlen)
--19892-- REDIR: 0xc7fe30 (malloc) redirected to 0x400587e (malloc)
--19892-- REDIR: 0x4c45bd0 (operator new[](unsigned int)) redirected to 0x4005ca1 (operator new[](unsigned int))
--19892-- REDIR: 0xc858d0 (memcpy) redirected to 0x4007a70 (memcpy)
--19892-- REDIR: 0xc84ee0 (memchr) redirected to 0x40069f0 (memchr)
--19892-- REDIR: 0x4c45a90 (operator new(unsigned int)) redirected to 0x4006049 (operator new(unsigned int))
--19892-- REDIR: 0xc85440 (mempcpy) redirected to 0x40072d0 (mempcpy)
1: 22: 35.499645 239.034012
--19892-- REDIR: 0x4c44560 (operator delete(void*)) redirected to 0x40051af (operator delete(void*))
2: 23: 179.292328 160.118195
3: 21: 9.101529 272.455933
4: 23: 232.154388 135.067001
==19892== Invalid write of size 4
==19892==    at 0x8048CF4: main (fp2.cpp:22)
==19892==  Address 0x401b03c is 0 bytes after a block of size 20 alloc'd
==19892==    at 0x4005903: malloc (vg_replace_malloc.c:195)
==19892==    by 0x8048C47: main (fp2.cpp:14)
==19892==
==19892== Invalid read of size 4
==19892==    at 0x8048D2F: main (fp2.cpp:24)
==19892==  Address 0x401b03c is 0 bytes after a block of size 20 alloc'd

1 Ответ

0 голосов
/ 21 апреля 2011

Когда вы прочитаете более 4 строк ввода, вы пройдете через конец Bpos, поскольку вы выделили только 5 значений.Первая итерация работала с индексом 1, поэтому 5-я итерация работает с индексом 5, но наибольшее допустимое значение индекса в этом массиве равно 4.

Также, это не имеет смысла, вы выделяете 20 файловуказатели для каждой строки:

FILE ** fRowPtr = (FILE **)malloc(sizeof(FILE *)*num_row*20);

И это пропустит первый (rowInd == 0) элемент, это то, что вы хотите?

for(rowInd=1; rowInd < num_row; rowInd++)
...