1

I am trying to load a binary file but I am getting:

realloc(): invalid next size

This is the struct im using in the following code:

typedef struct {
    int from;
    int to;
    int cost;
} edge_t;

typedef struct {
    int size;
    int capacity;
    edge_t *edges;
} graph_t;

Code:

#include <stdlib.h>
#include <stdio.h>
#include "graph.h" //this is the struct above

void load_bin(const char *fname, graph_t *graph) {
    graph->capacity = 1;
    graph->size = 0; 
    graph->edges = malloc(graph->capacity*sizeof(edge_t));
    FILE *myFile;
    myFile = fopen(fname, "r");

    if (myFile == NULL) {
        fprintf(stderr, "Error: file not found!\n");
        exit(100);
    }

    while(fread(&(graph->edges[graph->size].from), sizeof(edge_t), 3, myFile) == 3){
        graph->size++;
        if(graph->capacity == graph->size){
            graph->capacity *=2;
            graph->edges=realloc(graph->edges, sizeof(edge_t)*graph->capacity);
        }
    }
}

EDIT: Tried to make a verifiable example, as requested.

int main(int argc, char *argv[])
{
   int ret = 0;
   if (argc > 2) {
      graph_t *graph = allocate_graph();
      fprintf(stderr, "Load bin file '%s'\n", argv[1]);
      load_bin(argv[1], graph);
      fprintf(stderr, "Save txt file '%s'\n", argv[2]);
      save_txt(graph, argv[2]);
      free_graph(&graph);
   } else {
      fprintf(stderr, "Usage %s input_bin_file output_txt_file\n", argv[0]);
      ret = -1;
   }
   return ret;
}

This function and load are located in the same file and are called from main

graph_t *allocate_graph(){
    return calloc(1, sizeof(graph_t));
}

From what I checked, it means I do not change the size properly on realloc, but I thought i was?

Thanks.

anon
  • 357
  • 5
  • 20
  • 1
    Include the calling code in your example (i.e. put together a `main()` that invokes `load_txt` and produces your error, then [add it to your question](https://stackoverflow.com/posts/53902751/edit)). Likewise, include your `#include` stack. Its important. – WhozCraig Dec 23 '18 at 10:40
  • 2
    warning with _feof_, I encourage you to replace the loop by `while (fscanf(...) == 3)` – bruno Dec 23 '18 at 10:43
  • 2
    Its worse than that. The attempt at loop breaking via the `if(!fscanf...` logic is broken anyway. If you process no arguments because end-of-file is encountered, `EOF` is the result, not `0`. Therefore that test is pointless, and further fuels the need to properly code the `while` condition as described here: [Why is “while ( !feof (file) )” always wrong?](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong). – WhozCraig Dec 23 '18 at 10:49
  • Except the _danger_ with _feof_ I do not see something wrong in your code. Run your program in a debugger or print the size before to _realloc_ to help to understand – bruno Dec 23 '18 at 10:51
  • Will try with the other while @bruno. – anon Dec 23 '18 at 10:53
  • Thanks for the link with explanation @WhozCraig. – anon Dec 23 '18 at 10:54
  • Still getting the `invalid next size` error... – anon Dec 23 '18 at 10:56
  • 1
    So where's `load_bin` and what does `allocate_graph` do. Putting all this together will build a [mcve]. Add them to your question code. I'm curious about `free_graph;` as well, for that matter. – WhozCraig Dec 23 '18 at 10:58
  • Print out `graph->capacity` before `realloc`, I suspect you are overflowing it so the value wraps to negative or zero. – Janne Tuukkanen Dec 23 '18 at 11:08
  • Funny thing though, i added wrong function. Sorry. – anon Dec 23 '18 at 11:09
  • the problem is not the _realloc_ but the _fread_, replace 3 by 1 else you read after the allocated memory – bruno Dec 23 '18 at 11:17

1 Answers1

1

the while is invalid, must be

while(fread(&(graph->edges[graph->size].from), sizeof(edge_t), 1, myFile) == 1)

because currently you read 3 elements and go out of the allocated memory

P.S. out of that, are you sure you read correctly the file ? you suppose the content is consecutive 3 values on sizeof(int) bytes, without separator etc

bruno
  • 32,421
  • 7
  • 25
  • 37