I want to get timestamp for my log in c. i have written a function to get timestamp. But when i return the variable i m getting different value.
My code:
<
You are returning a pointer to a stack variable and therefore it is not valid to use after the function returns:
char buffer[16];
Will be allocated on the stack in the function. When you return the stack is cleaned up and buffer
is no longer valid. With minimal changes this is probably a better function signature:
void get_timestamp( char *buffer, size_t buffLen )
The assumption being that you have properly allocated space for buffer
before calling get_timestamp
.
In answering this question I wanted a function that was simple, thread friendly, did not return a char* (which is often tedious to manage), thread-safe and could stand on its own feet. I have an aversion to functions that return char* or pointers that must be managed.
The function below does not call malloc.
The function takes no parameters and returns a timestamp. I think it works well.
struct Timestamp {
time_t seconds;
long milliseconds;
char timestring[32];
};
struct Timestamp getTimestamp()
{
char timebuffer[32] = {0};
struct timeval tv = {0};
struct tm *tmval = NULL;
struct tm gmtval = {0};
struct timespec curtime = {0};
struct Timestamp timestamp;
int i = 0;
// Get current time
clock_gettime(CLOCK_REALTIME, &curtime);
// Set the fields
timestamp.seconds = curtime.tv_sec;
timestamp.milliseconds = round(curtime.tv_nsec/1.0e6);
if((tmval = gmtime_r(×tamp.seconds, &gmtval)) != NULL)
{
// Build the first part of the time
strftime(timebuffer, sizeof timebuffer, "%Y-%m-%d %H:%M:%S", &gmtval);
// Add the milliseconds part and build the time string
snprintf(timestamp.timestring, sizeof timestamp.timestring, "%s.%03ld", timebuffer, timestamp.milliseconds);
}
return timestamp;
}
int main()
{
char timebuffer[64] = {0};
int i = 0;
struct timespec sleeptime = {0, 5000000L};
struct Timestamp timestamp;
for (i=0; i < 20; i++)
{
timestamp = getTimestamp();
printf("Time is: %s \n", timestamp.timestring);
nanosleep(&sleeptime, NULL);
}
return 0;
}
The string you're returning is an automatic variable. When you exit the function accessing this variable is impossible. According to the specs it's undefined behavior. Use malloc to allocate the string and you'll be fine. Just don't forget to free it afterwards.
buffer[16]
is a local array, which stops existing at the end of char* get_timestamp()
function. Then you return a pointer to an array that does not exist.
As the other said, you're using data that resides on the stack and stops existing once you leave the function that declared it. I see two simple possibilities to solve this problem:
Option 1: allocate the buffer variable in the calling function, and pass a pointer into get_timestamp
void get_timestamp( char *buffer, size_t buffersize ) {
....
strftime (buffer,buffersize,"%G%m%d%H%M%S",timeinfo);
}
int main()
{
char buffer[16];
puts(get_timestamp(buffer,16));
return 0;
}
Note/Edit: I folded unwind's very valid remark regarding passing the size of buffer into this suggested solution.
Option 2: if you cannot or don't want to change the signature of your function you can use a static variable, but don't forget that static variables can cause issues in multithreaded programs.
static char buffer[16];
char* get_timestamp(){
...
}
int main()
{
puts(get_timestamp());
return 0;
}
You could of course use malloc
but that seems overkill in this situation, and is more error prone than the two fixes I described.