具有多个被识别为只有一个成员的结构的列表
List with many structs recognized as having just one member
在下面的程序中,我将包含许多不同日期的data
传递给函数GetAvgDayVolm()
,然后该函数中的cout
语句输出1
。
但是它应该输出比1
更多的数据,因为data
中有不止一个不同的日期。虽然程序根本没有进入if
语句,但看起来curTime
已经更改。你看到什么不对吗?
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;
}
在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,或者先保存结果。
问题是您使用的是从gmtime()
函数返回的指针,它基本上是每个使用时间函数的调用程序共享的公共内存块。解决这个问题的方法是将值复制出去(通过取消引用返回的指针),而不是保留指针的副本。
在多线程环境中,您还需要采取进一步的预防措施。使用线程安全版本之一(gmtime_r
/gmtime_s
)或使用互斥(慢速)同步访问。
此外,我会考虑将函数参数从指针更改为常量引用,因为它总是被假设存在,并且不会被函数修改。
以下是您功能的可能解决方案:
// 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??
}
相关文章:
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 大家好,当一个类有一个向量作为它的数据成员时,为什么它的大小总是24?
- 我们可以有一个 setter 成员函数作为从 const 对象引用的 const 吗?
- 我的类中应该有一个Allocator作为成员变量吗
- 有一个可迭代的容器,其中的成员在编译时是已知的
- 如果我们有一个基*类,如何访问派生模板类的成员函数
- 为什么在std::optional的某些实现中有一个虚拟工会成员?
- 有没有办法为静态对象成员定义一个符合开关标准的常量?
- 为什么有一个额外的 & 将非静态成员函数的地址传递给 C++ 中的线程?
- 从指向成员的指针的模板推导,其中至少有一个指向成员的指针是已知的
- 长镜头 -- 可能有一个静态类成员,该类成员具有访问非静态成员的 lambda
- 难道不应该有一个类似于"this"的与名称无关的类指针供成员函数在C++中引用吗?
- 如何维护类成员的顺序,并且仍然有一个可工作的构造函数
- 如果我有一个向量(或类似的东西)成员变量,那么move构造函数看起来怎么样
- 一个类本身有一个静态成员的功能是什么?
- 为什么嵌套类不能有一个类型为封闭类的成员?
- 我可以有一个仅使用工厂方法创建的成员变量吗?
- 是否可以有一个带有模板元素的类成员数组
- 只有当c++中有活动的东西时,才有一个额外的数据成员