2

I am trying to use realloc to allocate more memory to my array, everytime a while loop reads a set of data.

This is the function

void loadStats(Database *db){
  FILE *file = fopen("stats.txt", "r");
  int i = 0;
  while (fscanf(file,"%s %d/%d %d.%d %s - %s %d - %d %f", 
    &db[i].dayname, &db[i].day, &db[i].month, &db[i].hour, &db[i].minute,
    &db[i].hometeam, &db[i].awayteam, &db[i].homescore, &db[i].awayscore, &db[i].spectators) != EOF){
    db[i].spectators = db[i].spectators * 1000;
    i++;
    db = realloc(db, sizeof(db) + sizeof(Database));
  }
  fclose(file);
}

This is the file I am trying to read: stats.txt

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

typedef struct{
  char dayname[3];
  int day;
  int month;
  int hour;
  int minute;
  char hometeam[3];
  char awayteam[3];
  int homescore;
  int awayscore;
  float spectators;
} Database;

void loadStats(Database *db);
void printStats(Database *db);

int main(){
  Database *db = malloc(sizeof(Database));
  loadStats(db);
  printStats(db);
  return 0;
}

void loadStats(Database *db){
  FILE *file = fopen("stats.txt", "r");
  int i = 0;
  while (fscanf(file,"%s %d/%d %d.%d %s - %s %d - %d %f", 
    &db[i].dayname, &db[i].day, &db[i].month, &db[i].hour, &db[i].minute,
    &db[i].hometeam, &db[i].awayteam, &db[i].homescore, &db[i].awayscore, &db[i].spectators) != EOF){
    db[i].spectators = db[i].spectators * 1000;
    i++;
    db = realloc(db, sizeof(db) + sizeof(Database));
  }
  fclose(file);
}

void printStats(Database *db){
    int i;
    printf("Enter array number.\n");
    scanf("%d", &i);
    printf("db[%d].dayname = %s\ndb[%d].day = %d\ndb[%d].month = %d\ndb[%d].hour = %d\ndb[%d].minute = %d\n"
           "db[%d].hometeam = %s\ndb[%d].awayteam = %s\ndb[%d].homescore = %d\ndb[%d].awayscore = %d\ndb[%d].spectators = %f\n\n", 
            i, db[i].dayname, i, db[i].day, i, db[i].month, i, db[i].hour, i, db[i].minute,
            i, db[i].hometeam, i, db[i].awayteam, i, db[i].homescore, i, db[i].awayscore, i, db[i].spectators);
}

Edit: The problem is that this crashes, I've tried without using realloc and just allocating a fixed amount with malloc, which works, however if the data increases it wouldn't. So I'm trying to make the code adaptive to the amount of data read.

Fisker
  • 41
  • 7
  • And what is the question? – Martin R Nov 28 '15 at 12:17
  • 1
    Most probably a duplicate of http://stackoverflow.com/questions/9478044/realloc-is-not-resizing-array-of-pointers – `realloc(db, sizeof(db) + sizeof(Database))` does not what you think it does. – Martin R Nov 28 '15 at 12:19

1 Answers1

3

First of all, let me tell you

 db = realloc(db, sizeof(db) + sizeof(Database));

is very bad way of coding, in case realloc() fails, you'll end up losing the actual pointer, too. A better way of getting things done would be (pseudo code)

Database * temp = NULL;
temp = realloc(db, sizeof(db) + sizeof(Database));
if (temp)
  db = temp;

That said, db being a pointer, sizeof(db) will always give you the size of the pointer, not the amount of memory allocated to it. You have to maintain and update a separate counter holding the size while using the new size in realloc(). Something like

 realloc(db, counter * sizeof(Database));  //counter is updated after every allocation

should do the job for you.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • Used (i + 1) as counter and it works. Thanks a lot for the help. – Fisker Nov 28 '15 at 13:08
  • If the code which uses realloc() would simply terminate in the event of failure, I don't think freeing up the old pointer in that situation would be important. Actually, in some C implementations--especially under Linux--the fact that allocations appear to succeed does not guarantee that they are returning a pointer to usable storage, so there's not much point trying to continue after allocation failures. – supercat Oct 23 '16 at 21:03