seg fault caused by malloc and sscanf in a function

不想你离开。 提交于 2019-12-11 09:04:54

问题


I want to open a text file (see below), read the first int in every line and store it in an array, but I get an segmentation fault. I got rid of all gcc warnings, I read through several tutorials I found on the net and searched stackoverflow for solutions, but I could't make out, what I am doing wrong.

It works when I have everything in the main function (see example 1), but not when I transfer it to second function (see example 2 further down). In example 2 I get, when I interpret gdb correctly a seg fault at sscanf (line,"%i",classes[i]);.

I'm afraid, it could be something trivial, but I already wasted one day on it.

Thanks in advance.

[Example 1] Even though that works with everything in main:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

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;
}

[Example 2] This does not with the functionality transfered to a function:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

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;
}

[Content of 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
...

回答1:


This:

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

is probably wrong. You need to dereference there too, try:

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

This is because classes is a pointer to an array of integers. You want the address of one of those integers, so that sscanf() can write the parsed number there. Therefore, you must first dereference classes to get the array, then say that you want the address of element number i in that array.

You could also use

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

Which might be clearer, depending on how comfortable you are with these things.




回答2:


The problem is you're applying the [] operator to an int* in the first case and an int** in the second. The int** is like a 2d array, when you use the [] operator in conjunction with the int** you are indexing into an array of int*. In your case this is not what you want, because you only initialize the first the first entry in this array. So when you access classes[1] it will crash because it's uninitialized. You could avoid yourself this confusion by passing in the pointer as a reference instead of a double pointer:

int*& classes instead of int** classes

Then you could use the same code as from your main function.



来源:https://stackoverflow.com/questions/2914766/seg-fault-caused-by-malloc-and-sscanf-in-a-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!