seg, вызванный malloc и sscanf в функции

Я хочу открыть текстовый файл (см. Ниже), прочитать первый int в каждой строке и сохранить его в массиве, но я получаю ошибку сегментации. Я избавился от всех gcc-предупреждений, я прочитал несколько руководств, которые я нашел в сети, и искал stackoverflow для решений, но я не мог понять, что я делаю неправильно.

Он работает, когда у меня есть все в основной функции (см. Пример 1), но не тогда, когда я переношу его на вторую функцию (см. Пример 2 ниже). В примере 2 я получаю, когда я правильно интерпретирую gdb seg-ошибку в sscanf (line,"%i",classes[i]); ,

Боюсь, это может быть что-то тривиальное, но я уже потратил впустую на этот день.

Заранее спасибо.

[Пример 1] Хотя это работает со всем в основном:

 #include #include #include const int LENGTH = 1024; int main() { char *filename="somedatafile.txt"; int *classes; int lines; FILE *pfile = NULL; char line[LENGTH]; pfile=fopen(filename,"r"); int numlines=0; char *p; while(fgets(line,LENGTH,pfile)){ numlines++; } rewind(pfile); classes=(int *)malloc(numlines*sizeof(int)); if(classes == NULL){ printf("\nMemory error."); exit(1); } int i=0; while(fgets(line,LENGTH,pfile)){ printf("\n"); p = strtok (line," "); p = strtok (NULL, ", "); sscanf (line,"%i",&classes[i]); i++; } fclose(pfile); return 1; } в #include #include #include const int LENGTH = 1024; int main() { char *filename="somedatafile.txt"; int *classes; int lines; FILE *pfile = NULL; char line[LENGTH]; pfile=fopen(filename,"r"); int numlines=0; char *p; while(fgets(line,LENGTH,pfile)){ numlines++; } rewind(pfile); classes=(int *)malloc(numlines*sizeof(int)); if(classes == NULL){ printf("\nMemory error."); exit(1); } int i=0; while(fgets(line,LENGTH,pfile)){ printf("\n"); p = strtok (line," "); p = strtok (NULL, ", "); sscanf (line,"%i",&classes[i]); i++; } fclose(pfile); return 1; } в #include #include #include const int LENGTH = 1024; int main() { char *filename="somedatafile.txt"; int *classes; int lines; FILE *pfile = NULL; char line[LENGTH]; pfile=fopen(filename,"r"); int numlines=0; char *p; while(fgets(line,LENGTH,pfile)){ numlines++; } rewind(pfile); classes=(int *)malloc(numlines*sizeof(int)); if(classes == NULL){ printf("\nMemory error."); exit(1); } int i=0; while(fgets(line,LENGTH,pfile)){ printf("\n"); p = strtok (line," "); p = strtok (NULL, ", "); sscanf (line,"%i",&classes[i]); i++; } fclose(pfile); return 1; } 

[Пример 2] Это не связано с функциональностью, переданной функции:

 #include #include #include const int LENGTH = 1024; void read_data(int **classes,int *lines, char *filename){ FILE *pfile = NULL; char line[LENGTH]; pfile=fopen(filename,"r"); int numlines=0; char *p; while(fgets(line,LENGTH,pfile)){ numlines++; } rewind(pfile); * classes=(int *)malloc(numlines*sizeof(int)); if(*classes == NULL){ printf("\nMemory error."); exit(1); } int i=0; while(fgets(line,LENGTH,pfile)){ printf("\n"); p = strtok (line," "); p = strtok (NULL, ", "); sscanf (line,"%i",classes[i]); i++; } fclose(pfile); *lines=numlines; } int main() { char *filename="somedatafile.txt"; int *classes; int lines; read_data(&classes, &lines,filename) ; for(int i=0;i<lines;i++){ printf("\nclasses[i]=%i",classes[i]); } return 1; } в #include #include #include const int LENGTH = 1024; void read_data(int **classes,int *lines, char *filename){ FILE *pfile = NULL; char line[LENGTH]; pfile=fopen(filename,"r"); int numlines=0; char *p; while(fgets(line,LENGTH,pfile)){ numlines++; } rewind(pfile); * classes=(int *)malloc(numlines*sizeof(int)); if(*classes == NULL){ printf("\nMemory error."); exit(1); } int i=0; while(fgets(line,LENGTH,pfile)){ printf("\n"); p = strtok (line," "); p = strtok (NULL, ", "); sscanf (line,"%i",classes[i]); i++; } fclose(pfile); *lines=numlines; } int main() { char *filename="somedatafile.txt"; int *classes; int lines; read_data(&classes, &lines,filename) ; for(int i=0;i<lines;i++){ printf("\nclasses[i]=%i",classes[i]); } return 1; } в #include #include #include const int LENGTH = 1024; void read_data(int **classes,int *lines, char *filename){ FILE *pfile = NULL; char line[LENGTH]; pfile=fopen(filename,"r"); int numlines=0; char *p; while(fgets(line,LENGTH,pfile)){ numlines++; } rewind(pfile); * classes=(int *)malloc(numlines*sizeof(int)); if(*classes == NULL){ printf("\nMemory error."); exit(1); } int i=0; while(fgets(line,LENGTH,pfile)){ printf("\n"); p = strtok (line," "); p = strtok (NULL, ", "); sscanf (line,"%i",classes[i]); i++; } fclose(pfile); *lines=numlines; } int main() { char *filename="somedatafile.txt"; int *classes; int lines; read_data(&classes, &lines,filename) ; for(int i=0;i<lines;i++){ printf("\nclasses[i]=%i",classes[i]); } return 1; } 

[Содержание somedatafile.txt]

 50 21 77 0 28 0 27 48 22 2 55 0 92 0 0 26 36 92 56 4 53 0 82 0 52 -5 29 30 2 1 37 0 76 0 28 18 40 48 8 1 37 0 79 0 34 -26 43 46 2 1 85 0 88 -4 6 1 3 83 80 5 56 0 81 0 -4 11 25 86 62 4 55 -1 95 -3 54 -4 40 41 2 1 53 8 77 0 28 0 23 48 24 4 37 0 101 -7 28 0 64 73 8 1 ... 

Это:

  sscanf (line,"%i",classes[i]); 

вероятно, неверно. Вам тоже нужно разыгрывать, попробуйте:

  sscanf (line,"%i", &(*classes)[i]); 

Это связано с тем, что classes являются указателями на массив целых чисел. Вам нужен адрес одного из этих целых чисел, так что sscanf() может написать там проанализированный номер. Следовательно, вы должны сначала разыменовать classes для получения массива, а затем сказать, что вам нужен адрес номера элемента i в этом массиве.

Вы также можете использовать

  sscanf (line,"%i", *classes + i); 

Что может быть яснее, в зависимости от того, насколько вам комфортно с этими вещами.

Проблема в том, что вы применяете оператор [] к int * в первом случае и int ** во втором. Int ** подобен массиву 2d, когда вы используете оператор [] в сочетании с int **, который вы индексируете в массив int *. В вашем случае это не то, что вы хотите, потому что вы только инициализируете первую первую запись в этом массиве. Поэтому, когда вы получаете доступ к classам [1], он будет разбит, потому что он не инициализирован. Вы могли бы избежать этой путаницы, передав указатель в качестве ссылки вместо двойной указатель:

 int*& classes instead of int** classes 

Затем вы можете использовать тот же код, что и от вашей основной функции.