The program crashes when printing the timestamp. I believe the error is located in the function void flightRec_PrflightRecData(flightRecRead* thisFlight) which is designed to do three things:
- declare the time struct flighttime, flighttime is in POSIX format.
- Localtime converts the POSIX time to a human-readable time.
- The fourth specifier prints the converted time using asctime which prints it in Www Mmm dd hh:mm:ss yyyy format.
The error is tb != NULL and shows other information specifying asctime.
What I have done to troubleshoot:
- Check for time header
- Checked pointers and addresses
- Turned deprecation off
- Checked the format specifier
Any assistance is appreciated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
typedef struct flightRec_struct { // declare a struct to match the format of the binary data
char FlightNum[7];
char OriginAirportCode[5];
char DestAirportCode[5];
int timestamp;
} flightRec;
typedef struct flightRecRead_struct { // declare a struct to match the format of your linked list
char FlightNum[7];
char OriginAirportCode[5];
char DestAirportCode[5];
int timestamp;
struct flightRec* nextFlight_ptr;
} flightRecRead;
// Print dataVal
void flightRec_PrflightRecData(flightRecRead* thisFlight) {
struct tm *flightTime;
flightTime = localtime(&thisFlight->timestamp);
printf("%s \t %s \t %s \t %s\n", thisFlight->FlightNum, thisFlight->OriginAirportCode,
thisFlight->DestAirportCode, asctime(flightTime));
return;
}
// Grab location pointed by nextFlight_ptr
flightRecRead* flightRec_GetNext(flightRecRead* thisFlight) {
return thisFlight->nextFlight_ptr;
}
int main(void) {
flightRec firstStruct;
flightRecRead* headObj = NULL;
flightRecRead* currObj = NULL;
flightRecRead* tailObj = NULL;
struct tm *flightTime;
int i = 0; //loop index
FILE* inFile = NULL;
inFile = fopen("acars.bin", "rb");
if (inFile == NULL) {
printf("Could not open file acars.bin.\n");
return -1;
}
if (!feof(inFile)) {
fread(&firstStruct, sizeof(flightRec), 1, inFile); // 2. read the file into that struct
headObj = (flightRecRead*)malloc(sizeof(flightRecRead)); // 3. make head point to that struct
strcpy(headObj->FlightNum, firstStruct.FlightNum);
strcpy(headObj->OriginAirportCode, firstStruct.OriginAirportCode);
strcpy(headObj->DestAirportCode, firstStruct.DestAirportCode);
headObj->timestamp = firstStruct.timestamp;
tailObj = (flightRecRead*)malloc(sizeof(flightRecRead)); // 4. make tail point to that struct
strcpy(tailObj->FlightNum, firstStruct.FlightNum);
strcpy(tailObj->OriginAirportCode, firstStruct.OriginAirportCode);
strcpy(tailObj->DestAirportCode, firstStruct.DestAirportCode);
tailObj->timestamp = firstStruct.timestamp;
headObj->nextFlight_ptr = tailObj;
tailObj->nextFlight_ptr = NULL;
}
while (!feof(inFile)) { // 5. while not end-of-file on the acars file:
fread(&firstStruct, sizeof(flightRec), 1, inFile); // 6. malloc a new struct
currObj = (flightRecRead*)malloc(sizeof(flightRecRead));
strcpy(currObj->FlightNum, firstStruct.FlightNum);
strcpy(currObj->OriginAirportCode, firstStruct.OriginAirportCode);
strcpy(currObj->DestAirportCode, firstStruct.DestAirportCode);
currObj->timestamp = firstStruct.timestamp;
currObj->nextFlight_ptr = NULL;
tailObj->nextFlight_ptr = currObj;
tailObj = currObj;
}
currObj = headObj; // Print the list
printf("FlightNum \t OriginAirportCode \t DestAirportCode \t Time \t \n");
while (currObj != NULL) {
flightRec_PrflightRecData(currObj);
currObj = flightRec_GetNext(currObj);
}
system("pause"); //return 0;
}
When I compile your code on a 64-bit Mac with GCC 5.1.0, it gives me a number of errors. Some of them, though, are consequences of the very stringent compilation options I use:
The 'unused variables' and 'no previous prototype' errors (would be warnings except that I used
-Werror
to force all warnings to be treated as errors).But the misuse of
int
as a surrogate fortime_t
could be a problem for you too. It may be less of an issue if you compile for a 32-bit platform.The other 'incompatible pointer type' warnings are worrying, too. In fact, your second structure definition is incorrect. You have:
The
struct flightRec *
is a pointer to an incomplete type. It is not astruct flightRec_struct
nor aflightRec
(nor astruct flightRecRead_struct
nor aflightRecRead
). In fact, you need it to be either astruct flightRecRead_struct *
or you need to predeclare the type and use aflightRecRead *
:You could simplify the assignment part of your code by using:
You could then assign the entire
flightRec
structure in a single line, rather than having to write out the multiplestrcpy()
operations, etc.Against this, if you need to use
time_t
and that is not the same size as anint
and the binary format is fixed externally, then you may need to do the member-wise copying after all.You should learn why
while (!feof(file))
is always wrong.Semi-fixed code:
timecrash.c
This code more or less works for me.
Sample run
The data generation assumes
time_t
is a 64-bit type aligned on an 8-byte boundary (7 null padding bytes before it), and is formatted in little-endian (as on Intel).The interrupt was necessary because my
pause
on Mac OS X doesn't terminate until interrupted (or otherwise sent a signal).