-1

i have got a problem with an array within an array of structs. My problem is that directly after assignment of the array the data is readable without problems but some time later i get the wrong results. here is my code:

struct time_on_off {
    struct tm time_on;
    struct tm time_off;
};

struct device {
    int mysqlid;
    int port;
    char name[12];
    struct tm time_on;
    struct tm time_off;
    struct time_on_off *time_on_off;
    int automatic;
    int state;
    struct tm timer;
    int man;
    int numtimers;
};

struct device devices[8];
char sqlquery[150];


int update(){

   MYSQL_RES *res;
   MYSQL_ROW row;

   day=currenttime->tm_wday;
   day=(day==0)?7:day;

   printf("Updating ... %d \n", day);
   res=connectsql("SELECT * FROM  `devices` AS A INNER JOIN manual AS B ON A.id = B.id");

   for (int i=0;(row = mysql_fetch_row(res)) != NULL;i++) {

      devices[i].mysqlid=atoi(row[0]);
      devices[i].port=atoi(row[3]);
      devices[i].automatic=1;
      devices[i].man=0;
      devices[i].timer.tm_min=0;
      devices[i].timer.tm_hour=0;
      strcpy(devices[i].name,row[1]);
      devices[i].state=atoi(row[5]);
      devices[i].numtimers=0;

      if(row[7]!=NULL){

        strptime(row[7],"%H:%M:%S", &devices[i].timer);
        devices[i].automatic=0;
        devices[i].man=atoi(row[6]);

      }
   }

  mysql_close(conn);

  for (int i=0; i<(sizeof(devices)/sizeof(struct device)); i++){

    sprintf(sqlquery,"SELECT * FROM  `timer` WHERE  `dayid` =  '%i' AND  `deviceid` =  '%i'",day,devices[i].mysqlid);
    res=connectsql(sqlquery);

    for (int o=0;(row = mysql_fetch_row(res))!= NULL;o++) {

      devices[i].time_on_off = (struct time_on_off *)  realloc(devices[i].time_on_off, devices[i].numtimers+1);
      strptime(row[2],"%H:%M:%S", &devices[i].time_on_off[o].time_on);
      strptime(row[3],"%H:%M:%S", &devices[i].time_on_off[o].time_off);
      printf("On: %i:%i \n", devices[i].time_on_off[o].time_on.tm_hour,devices[i].time_on_off[o].time_on.tm_min);
      printf("Off: %i:%i \n", devices[i].time_on_off[o].time_off.tm_hour,devices[i].time_on_off[o].time_off.tm_min);
     devices[i].numtimers++;
     devices[i].automatic=1;

     }
    mysql_close(conn);
  }

  for (int i=0; i<(sizeof(devices)/sizeof(struct device)); i++){

      printf("Name: %s \n", devices[i].name);
      printf("Port: %i \n", devices[i].port);
      printf("Automatic: %i \n", devices[i].automatic);
      printf("man: %i \n", devices[i].man);
      printf("Timer: %i:%i \n", devices[i].timer.tm_hour,devices[i].timer.tm_min);

      for (int o=0; o<devices[i].numtimers; o++){

           printf("On: %i:%i \n", devices[i].time_on_off[o].time_on.tm_hour,devices[i].time_on_off[o].time_on.tm_min);
           printf("Off: %i:%i \n", devices[i].time_on_off[o].time_off.tm_hour,devices[i].time_on_off[o].time_off.tm_min);
      }
  }
return 0;
}

the output is:

Updating ... 2 
On: 14:0 
Off: 16:0 <- thats the correct value
On: 16:0 
Off: 18:0 
On: 17:0 
Off: 19:0 
On: 15:8 
Off: 16:9 
Name: Poolpumpe 
Port: 0 
Automatic: 1 
man: 0 
Timer: 0:0 
On: 14:0 
Off: 1936681068:1633906540 <- here seems to be the error
Name: Poollicht 
Port: 1 
...

Has anyone got an idea for me? Thank you

user154501
  • 49
  • 5
  • 2
    I can say that I cannot see where your function start and ends. It's just a big jumble of lines. Next... – Martin James Mar 15 '16 at 10:27
  • 1
    Please put more effort into your questions, in this case: the formatting. This is hard to read due to incorrect indention and I bet lots of people see this and won't even bother to read it because of this. So it's in your own interest to get the formatting right. Also, have you stepped through your code with a debugger to analyze it? – DarkDust Mar 15 '16 at 10:29
  • I tried to clean it up. Thanks for your advice. – user154501 Mar 15 '16 at 10:44
  • Please make it readble. – sakthi Mar 15 '16 at 10:53

1 Answers1

2

Your (re)allocation is wrong, you do not allocate space for x entries, you only allocate x bytes:

devices[i].time_on_off = realloc(devices[i].time_on_off, devices[i].numtimers+1);

Your intention here is probably to have enough space for o+1 entries (o == devices[i].numtimers in your case). So it should be something like:

devices[i].time_on_off = realloc(devices[i].time_on_off, sizeof(struct time_on_off) * (o+1));

or:

devices[i].numtimers++;
devices[i].time_on_off = realloc(devices[i].time_on_off, sizeof(struct time_on_off) * devices[i].numtimers);

Also, don't cast the result pointer from malloc and realloc.

Community
  • 1
  • 1
DarkDust
  • 90,870
  • 19
  • 190
  • 224