好的,我已经尝试了我所知道的所有方法来阻止这个程序崩溃,但我就是不明白为什么。我能够用ctime将问题隔离到代码中,并且只做了一个小程序来演示哪里出了问题。这段代码编译时没有任何问题。
#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;
}这是我从调试中得到的一些文本。
调用堆栈
#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 ??() (??:??)这里还有来自同一构建的另一个调用堆栈。
#0 77BE708C ntdll!RtlTraceDatabaseLock() (C:\Windows\system32\ntdll.dll:??)
#1 00000000 0x6ccdaf66 in ??() (??:??)
#2 00000000 0x00000000 in ??() (??:??)它是一些特殊的构建选项吗?我使用的是-std=c++0x,但我决定不使用它来尝试这个程序,它仍然崩溃了。谢谢你的帮助,我已经试了一整天了。
发布于 2014-03-23 21:05:56
我认为问题出在这里:
struct tm* loctim=localtime(&t);
delete loctim;localtime返回一个指向静态缓冲区的指针。你不能释放它。这导致了一种“未定义的行为”。即,一些数据被置于不一致的状态,并且可能导致程序的另一个地方崩溃,这看起来可能与问题没有直接关系。
发布于 2014-03-23 21:09:29
发现此类问题的一个好方法是在valgrind下运行程序。它为您提供了非常准确的错误信息-
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)发布于 2014-03-23 21:10:35
您不能使用delete来释放不使用c++内存管理的localtime()的结果,它是一个c++操作符。在任何情况下,实际上都不需要释放localtime返回的值。
https://stackoverflow.com/questions/22591281
复制相似问题