0

My program stores matrix in binary files, when I try to "load" them during the same use of the program, everything works well.

However, when I close the program and use it later, it's impossible to access to the same files and I get a Segmentation fault (core dumped) error.

Here's the function that "loads" the matrixes :

void Loading(int mat**){
  char* name = malloc(sizeof(char)*20);
  printf("Enter name of the file");
  scanf("%s",name);
  FILE* file=fopen(name,"rb");
  if (file==NULL){
    printf("error opening file");
    exit(0);
  }
  fread(mat,sizeof(int)*M*M,1,file);
  fclose(fichier);
}

where M is a constant.

Again it works perfectly when I store/load mutliple times during the same use of the program

sorry for the mistakes I am not an english speaker

alk
  • 69,737
  • 10
  • 105
  • 255
Niyoel
  • 17
  • 2
  • Is `mat` buffer properly allocated? – m0skit0 Dec 13 '18 at 13:53
  • 2
    Please indent your code properly so it it readable. Readable code is essentially good for _you_. – Jabberwocky Dec 13 '18 at 13:55
  • 4
    The problem is most likely in the code that calls `Loading` which you didn't show. `Loading` looks more or less correct. BTW: `(int mat**)` is not C, should it be `(int **mat)`? Please show real code. Also read this: [ask] and [mcve]. – Jabberwocky Dec 13 '18 at 13:56
  • Also `int**` is neither a 2D array of integer nor points it to the same. – alk Dec 13 '18 at 14:04
  • @Jabberwocky: "*looks more or less correct*" more "less" then "more". – alk Dec 13 '18 at 14:06
  • 1
    To answer this we *at least* need to see the code that writes the file. Better also show how the array id allocated in both cases reading and writing. – alk Dec 13 '18 at 14:07
  • Possible duplicate https://stackoverflow.com/questions/35599371/reading-2d-array-from-binary-file-and-return-the-pointer-this-array-in-c – n. m. could be an AI Dec 13 '18 at 14:32
  • 1
    Please copy/paste the real code. – Lundin Dec 13 '18 at 14:52
  • @Niyoul - Just an etiquette suggestion for this site: Responding to the suggestions in the comment area is a good idea, both by making edits to your post, and responding to comments with comments of your own to address questions and suggestions. Your failure to do this so far is in part likely why you are seeing some down-votes and close votes. (as indicated clearly by one of the comment links.) Otherwise, this appears to be a reasonably well written question, and should not normally be seeing this many down/close-votes. – ryyker Dec 13 '18 at 15:21
  • 1
    @ryyker: "*Otherwise, this appears to be a reasonably well written question*" I object, the context is missing. Prose is not enough, we need to see code, else there would be just to much guessing. – alk Dec 13 '18 at 16:20
  • @Alk - _reasonably_ being the key word. I did not say perfect. But OP is after all a new user, and for a first question, it contains enough to allow suggestions to be made. Beyond these caveats, I cannot argue with you. It needs more information. – ryyker Dec 13 '18 at 16:22
  • @alk There is *more than enough information* in posted *code* to identify the problem and suggest a fix. – n. m. could be an AI Dec 14 '18 at 09:58

2 Answers2

2

As presented, the question is missing key elements to allow a full analysis, nor a complete answer. But with what is shown, here are some suggestions:

1) The reason(s) for your segmentation fault cannot be identified with absolute certainty because some of the pieces are missing from your post. However, given the fact that it works sometimes, and not others, suggests undefined behavior is playing a part. If I were to guess at the source of undefined behavior, it would be that you are passing around a double pointer variable int **mat, when only a single pointer variable int *mat is necessary (see prototype of fread() below.), further leading me to believe that memory for mat has not been correctly created. I suggest changing:

void Loading(int mat**) // double pointer is not needed here

to

void Loading(unsigned int mat*) //and memory allocation method adjusted accordingly.   

(See reason for unsigned in 3) below.)

2) The prototype for the function fread() is:

size_t fread (void *Buffer, size_t Element_Size, size_t Number_of_Elements, FILE *Stream);

In your call:

fread(mat,sizeof(int)*M*M,1,file);

Arguments 2 & 3 appear to be reversed. It should probably be written:

fread(mat, sizeof(unsigned int), M*M, file);

3) Why unsigned int verses int when working with binary data?:

  • Your post is not explicit on how the data is written to the file, or exactly what format it is in, but generally, when working with binary data, it is better to stick with unsigned types for the reasons listed here.
ryyker
  • 22,849
  • 3
  • 43
  • 87
1

You have a pointer to your buffer for matrix int **mat. The problem is, that this doesn't point to single continuous place in memory. int mat** is a pointer to array of pointers to int. This is a place in memory that should contain more pointers one stored after another. Each of them (int*) then should point into different arrays, that would finally contain array of integers.

Basically you use command fread to write whole data into the array of pointers. Maybe you don't have enough space to store your data at all. Even if you would, you need another kind of pointer. If you have one continuous array, you could point to it using int *. Then you would pick some element by calculating an index.

int *mtx = (int*) malloc(M*M*sizeof(int);
int x = 2, y = 3;
int index = y*M+x;
mtx[index] = 123; // write to matrix coordinates 2,3

You could use fread with this kind of buffer with no problem, just check how are matrix elements indexed in your input file, maybe the x,y is swapped.

nio
  • 5,141
  • 2
  • 24
  • 35
  • 2
    "Mangled arrays" is rather dinosaurish. Better version: `int (*mtx)[M] = malloc (sizeof(int[M][M])); mtx[x][y] = something;`. It even works in dinosaur C if `M` is an integer constant. – Lundin Dec 13 '18 at 14:56
  • @Lundin - I do not understand part of this comment. (I understand the part about avoiding mangled array contents.) But why are you suggesting this answer create more than just a simple (i.e. _single dimensional_) area of memory? The OP intent is clearly to read into a single contiguous area of memory. – ryyker Dec 13 '18 at 15:13
  • 1
    @ryyker Because a 1D matrix isn't much fun? – Lundin Dec 13 '18 at 15:16
  • Sorry for the dinosaur stuff. I tend to make solution from the point of view of OP. If I make easy understandable solution, OP can pick the solution right away and progress on. Maybe he won't learn that much. Anyway I am learning too, while answering questions. – nio Dec 13 '18 at 15:32
  • "*`int mat**` is a pointer to array of pointers to int*" unfortunately not. It is a pointer to a pointer to an `int`, nothing more nothing less. – alk Dec 13 '18 at 16:14