Segfault when using time.h

2

Ok I've been trying just about everything I know to get this program to stop crashing, but I just can't see why. I was able to isolate the problem to code with ctime, and just made a small program to demonstrate what's wrong. This code compiles without a problem.

#include<iostream>
#include<ctime>

int main();
time_t getDay(time_t t);
int diffDay(time_t end,time_t begin);

int main()
{
    time_t curTime=time(NULL);  //Assign current time
    time_t curDay=getDay(curTime);  //Assign beginning of day
    time_t yesterday=curDay-16*60*60;   //Assign a time that's within yesterday
    time_t dif=diffDay(curTime,yesterday); //Assign how many days are between yesterday and curTime


    std::cout << "Cur Time: " << curTime << '\n'
            << "Cur Day: " << curDay << '\n'
            << "Yes Day: " << dif << '\n' << std::flush;

    char a;
    std::cin >> a; ///Program crashes after here.

    return 0;
}

///Get beginning of day that t is a part of
time_t getDay(time_t t)
{
    //Get current time
    struct tm* loctim=localtime(&t);

    if(loctim==0)
        return 0;

    //Set loctim to beginning of day
    loctim->tm_sec=0;
    loctim->tm_min=0;
    loctim->tm_hour=0;

    //Create a int from the new time
    int reval=mktime(loctim);

    //Free memory
    delete loctim;

    return reval;
}

///Calculate how many days are between begin and end
int diffDay(time_t end,time_t begin)
{
    time_t eDay=getDay(end); //Get beginning of day end is a part of
    time_t bDay=getDay(begin); //Get beginning of day begin is a part of
    time_t dif=(eDay-bDay)/(24*60*60); //Get how many days (86400 seconds)

    return dif;
}

Here is some text I got from debugging.

Call Stack

#0 77BC3242 ntdll!LdrLoadAlternateResourceModuleEx() (C:\Windows\system32\ntdll.dll:??)
#1 00000000 0x6d067ad3 in ??() (??:??)
#2 00000000 0x00000018 in ??() (??:??)
#3 77BC3080 ntdll!LdrLoadAlternateResourceModuleEx() (C:\Windows\system32\ntdll.dll:??)
#4 00000000 0x00000018 in ??() (??:??)
#5 77C60FCB ntdll!TpCheckTerminateWorker() (C:\Windows\system32\ntdll.dll:??)
#6 00000000 0x007f0000 in ??() (??:??)
#7 00000000 0x50000163 in ??() (??:??)
#8 00000000 0x00000018 in ??() (??:??)
#9 77C1AC4B ntdll!RtlReAllocateHeap() (C:\Windows\system32\ntdll.dll:??)
#10 00000000    0x007f0000 in ??() (??:??)
#11 00000000    0x50000163 in ??() (??:??)
#12 00000000    0x00000018 in ??() (??:??)
#13 77BC3080    ntdll!LdrLoadAlternateResourceModuleEx() (C:\Windows\system32\ntdll.dll:??)
#14 00000000    0x00000018 in ??() (??:??)
#15 769A9D45    msvcrt!malloc() (C:\Windows\syswow64\msvcrt.dll:??)
#16 769AF5D3    strcpy_s() (C:\Windows\syswow64\msvcrt.dll:??)
#17 769B2B18    open_osfhandle() (C:\Windows\syswow64\msvcrt.dll:??)
#18 00000000    0x00000018 in ??() (??:??)
#19 769B3C7D    msvcrt!_get_fmode() (C:\Windows\syswow64\msvcrt.dll:??)
#20 769BA6A0    msvcrt!_fsopen() (C:\Windows\syswow64\msvcrt.dll:??)
#21 00000000    0xc3458a06 in ??() (??:??)
#22 00000000    0x00000000 in ??() (??:??)

Also here's another call stack from the same build.

#0 77BE708C ntdll!RtlTraceDatabaseLock() (C:\Windows\system32\ntdll.dll:??)
#1 00000000 0x6ccdaf66 in ??() (??:??)
#2 00000000 0x00000000 in ??() (??:??)

Is it some special build option? I was using -std=c++0x but decided to try the program without it and it still crashed. Thanks for any help, I've been trying to fix this all day.

c++
segmentation-fault
undefined-behavior
localtime
asked on Stack Overflow Mar 23, 2014 by z121231211 • edited Jun 20, 2020 by Community

4 Answers

6

I think that the problem is here:

  struct tm* loctim=localtime(&t);
  delete loctim;

localtime returns a pointer to a static buffer. You shall not free it. This is causing an "undefined behaviour". i.e. some data are put into an inconsistent state and may cause crash at another place of program which may seem not to be directly related to the problem.

answered on Stack Overflow Mar 23, 2014 by Marian
2

A nice way to find such problems is to run the program under valgrind. It gives you very accurate information about what is going wrong -

vlap:~/src $ valgrind ./a.out
==29314== Memcheck, a memory error detector
==29314== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==29314== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==29314== Command: ./a.out
==29314== 
==29314== Invalid free() / delete / delete[] / realloc()
==29314==    at 0x4C29E6C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==29314==    by 0x400D2A: getDay(long) (test.cpp:44)
==29314==    by 0x400BEE: main (test.cpp:11)
==29314==  Address 0x59f5560 is 0 bytes inside data symbol "_tmbuf"
==29314==
==29314== Invalid free() / delete / delete[] / realloc()
==29314==    at 0x4C29E6C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==29314==    by 0x400D2A: getDay(long) (test.cpp:44)
==29314==    by 0x400D4D: diffDay(long, long) (test.cpp:52)
==29314==    by 0x400C13: main (test.cpp:13)
==29314==  Address 0x59f5560 is 0 bytes inside data symbol "_tmbuf"
==29314==
==29314== Invalid free() / delete / delete[] / realloc()
==29314==    at 0x4C29E6C: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==29314==    by 0x400D2A: getDay(long) (test.cpp:44)
==29314==    by 0x400D5D: diffDay(long, long) (test.cpp:53)
==29314==    by 0x400C13: main (test.cpp:13)
==29314==  Address 0x59f5560 is 0 bytes inside data symbol "_tmbuf"
==29314==
Cur Time: 1395580379
Cur Day: 1395529200
Yes Day: 1
a
==29314==
==29314== HEAP SUMMARY:
==29314==     in use at exit: 0 bytes in 0 blocks
==29314==   total heap usage: 12 allocs, 15 frees, 1,846 bytes allocated
==29314==
==29314== All heap blocks were freed -- no leaks are possible
==29314==
==29314== For counts of detected and suppressed errors, rerun with: -v
==29314== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 3 from 3)
answered on Stack Overflow Mar 23, 2014 by Vishesh Handa
0

You cant use delete, which is a c++ operator, to free the result of localtime() which doesnt use c++ memory management. In any case, you dont actually need to release the value returned by localtime.

answered on Stack Overflow Mar 23, 2014 by 6EQUJ5
0

You can use the cmd or the terminal to get the time in a file on cmd: echo %time% > time.txt and on linux terminal: date > time.txt You can run the commsnd with: system(command) And than you read the file.

answered on Stack Overflow Feb 25, 2017 by Tim Wendt

User contributions licensed under CC BY-SA 3.0