在以下程序中,我将包含许多不同日期的data
传递给函数GetAvgDayVolm()
,此函数中的cout
语句然后输出1
。< / p>
但它的输出应超过1
,因为data
中有多个不同的日期。虽然程序根本没有进入curTime
语句,但看起来if
已更改。你看错了吗?
long int GetAvgDayVolm(list<struct DataPoint>* data)
{
long long int totalVolm = 0;
long int numOfDays = 1;
struct DataPoint dp = (*data).front();
time_t rawTime2 = dp.timeStamp;
time_t rawTime = 0;
struct tm* curTime = gmtime(&rawTime2);
struct tm* movingTime = new struct tm ();
for(list<struct DataPoint>::iterator it = (*data).begin(); it != (*data).end(); ++it)
{
rawTime = (*it).timeStamp;
movingTime = gmtime(&rawTime);
totalVolm += (*it).volm;
if(curTime->tm_mday != movingTime->tm_mday ||
curTime->tm_mon != movingTime->tm_mon ||
curTime->tm_year != movingTime->tm_year)
{
numOfDays = numOfDays + 1;
curTime = movingTime;
}
}
cout<<numOfDays<<endl;
return 0;
}
答案 0 :(得分:3)
在gmtime联机帮助页中,NOTES部分说:
The four functions asctime(), ctime(), gmtime() and localtime() return a pointer to static data and hence are not thread-safe
所以在你的代码中,curTime和movingTime指向相同的静态数据区,你应该使用gmtime_r,或者只保存结果。
答案 1 :(得分:2)
问题是你正在使用从gmtime()
函数返回的指针,它基本上是一个公共的内存块,每个调用者使用时间函数共享。修复它的方法是复制值(通过解除引用返回的指针)而不是保留指针的副本。
在多线程环境中,您还需要采取进一步的预防措施。使用其中一个线程安全版本(gmtime_r
/ gmtime_s
)或使用互斥锁(慢速)同步访问。
此外,我会考虑将您的函数参数从指针更改为 const引用,因为它始终假定存在且不会被函数修改。
以下是您的功能的可能解决方案:
// pass by const reference if possible because
// the list is assumed to exist and is never modified
long int GetAvgDayVolm(const list<DataPoint>& data)
{
if(data.empty()) // possible crash later without this check
return 0;
long long int totalVolm = 0;
long int numOfDays = 1;
DataPoint dp = data.front(); // REQUIRES list contains at least one element
time_t rawTime2 = dp.timeStamp;
time_t rawTime = 0;
// don't use pointer here, dereference the
// returned value
std::tm curTime = *gmtime(&rawTime2);
// no need for pointer here - dereference the
// return value of gmtime() instead
std::tm movingTime;
for(list<DataPoint>::const_iterator it = data.begin(); it != data.end(); ++it)
{
rawTime = it->timeStamp;
movingTime = *gmtime(&rawTime);
totalVolm += it->volm;
if(curTime.tm_mday != movingTime.tm_mday ||
curTime.tm_mon != movingTime.tm_mon ||
curTime.tm_year != movingTime.tm_year)
{
numOfDays = numOfDays + 1;
curTime = movingTime;
}
}
cout<<numOfDays<<endl;
return 0; // is this correct??
}