2013-08-30 2 views
0

Я пытаюсь написать парсер csv в C, но каждый раз, когда я получаю segfault в этой функции. Я не знаю, как это исправить.Segfault в моей функции csv_loader()

char*** csv_loader(char *filename){ 
FILE* file_xx; 
file_xx = fopen(filename, "r"); 
if(file_xx==NULL){ 
    printf("Failed to open File, no such file or directory!\n"); 
    return 0; 
} 
int c_=0; 
int **linenumbers; 
int l=lines(filename); 
linenumbers=malloc(sizeof(int)*l); 
char*** loaded_csv; 
int counter_line=0; 
int counter_row=0; 
loaded_csv=malloc(sizeof(char **) *l); 
loaded_csv[0][0]=malloc(getfirstcolumn(filename)*sizeof(char)+2); 
if(NULL==loaded_csv){ 
    printf("Failed to initialize 'char** loaded_csv'!\n"); 
    return 0; 
} 
int c_c=0; 
int *cm=get_column_map(filename); 
for(c_c=0;c_c<l;c_c++){ 
    loaded_csv[c_c]=malloc(sizeof(char *)*cm[c_c]); 
} 
while(c_!=EOF){ 
    c_=getc(file_xx); 
    if(c_=='\n'){ 
     linenumbers[counter_line][cm[counter_line]]=counter_row+2; 
     loaded_csv[counter_line][cm[counter_line]]=malloc(counter_row*sizeof(char)); 
     if(NULL == loaded_csv[counter_line][cm[counter_line]]){ 
     return 0; 
     } 
     loaded_csv[counter_line][counter_row]='\0'; 
     counter_row=0; 
     counter_line++; 
    }else{ 
     if(c_==','){ 
      counter_row=0; 
     }else{ 
      counter_row++; 
     } 
    } 
} 
fclose(file_xx); 
FILE*fgetsread; 
fgetsread=fopen(filename, "r"); 
int ident, ident_c; 
for(ident=0;ident<l;ident++){ 
    for(ident_c=0;ident_c<cm[ident];ident_c++){ 
     fgets(loaded_csv[ident][ident_c], linenumbers[ident][ident_c], fgetsread); 
     loaded_csv[ident][ident_c][linenumbers[ident][ident_c]-2]='\0'; 
    } 
} 
fclose(fgetsread); 
free(linenumbers); 
return loaded_csv; 
} 

Отладчик говорит, что эта строка:

loaded_csv[0][0]=malloc(getfirstcolumn(filename)*sizeof(char)+2); 

Кто-нибудь знает, что это ошибка? Я еще новичок в C и в любом случае попытайтесь понять таНос вещь ...

PS: другие функции здесь: http://pastebin.com/VQZ4d5UU

ответ

1

Итак, вы выделили место на линии прямо перед:

loaded_csv=malloc(sizeof(char **) *l); 

Это прекрасно и денди, но loaded_csv[0] еще не инициализирован где-то у вас. Итак, когда вы делаете следующую строку

loaded_csv[0][0]=malloc(getfirstcolumn(filename)*sizeof(char)+2); 

вы пытаетесь установить переменную, расположенную в некотором случайном месте (там, где loaded_csv[0] случается прямо тогда).

Если вы хотите прикоснуться к loaded_csv[0][0], вы должны убедиться, что loaded_csv[0] указывает на действительной памяти первого (возможно, путем выделения памяти для него через mallocперед тем вы выделить что-то для loaded_csv[0][0].)

+0

спасибо, я сделал это слишком поздно, я выделил его прямо на этой линии: для (c_c = 0; c_c <л; c_C++) { loaded_csv [c_c] = таНос (SizeOf (Char *) * см [ c_c]); } } Теперь я переключил его прямо над линией ошибки, и следующая строка появляется на линии: Простыни [counter_line] [cm [counter_line]] = counter_row + 2; –

+0

Редактирование: Я видел это сам, это ложное распределение linenumbers –

0

Вы «ве есть проблемы с этой линии:

loaded_csv[0][0]=malloc(getfirstcolumn(filename)*sizeof(char)+2); 

, которые предполагают, что вы не выделение и инициализацию loaded_csv [0] [0] правильно.

Вот пример того, как инициализировать и использовать символ *** вар:

#include <windows.h> 
#include <ansi_c.h> 
char *** Create3D(int p, int c, int r); 
int main(void) 
{ 
    char ***pppVar; 

    pppVar = Create3D(10,10,10); 
    //test pppVar; 
    strcpy(pppVar[0][0], "asdfasf"); 
    strcpy(pppVar[0][1], "the ball"); 

    return 0; 
} 

char *** Create3D(int p, int c, int r) 
{ 
    char *space; 
    char ***arr; 
    int x,y; 

    space = calloc (p*c*r*sizeof(char),sizeof(char)); 
    arr = calloc(p * sizeof(char **), sizeof(char)); 
    for(x = 0; x < p; x++) 
    { 
     arr[x] = calloc(c * sizeof(char *),sizeof(char)); 
     for(y = 0; y < c; y++) 
     { 
      arr[x][y] = ((char *)space + (x*(c*r) + y*r)); 
     } 
    } 
    return arr; 
} 

Обязательно следить и бесплатный (х) соответственно.

+0

Мне не нравится calloc(), потому что он устанавливает фиксированный блок памяти непосредственно на 0, мне нравится динамический в malloc(), потому что вы используете только память тебе нужно. Но исправьте меня, если я ошибаюсь ... –

+0

Оба calloc и malloc выделяют фиксированный объем памяти, но malloc не гарантирует содержимое выделенной памяти. то есть выделенное пространство имеет неопределенное значение. Это может привести к проблемам, если вы не будете осторожны. Тем не менее, оба работают нормально, calloc - это только предпочтение для меня. – ryyker

Смежные вопросы