昨天我读了一些同事的代码并发现了这个:
class a_class { public: a_class() {...} int some_method(int some_param) {...} int value_1; int value_2; float value_3; std::vectoreven_more_values; /* and so on */ } a_class a_instances[10]; void some_function() { do_stuff(); do_more_stuff(); memset(a_instances, 0, 10 * sizeof(a_class)); // <===== WTF? }
这是合法的(WTF线,而不是公共属性)?对我来说它闻起来真的非常糟糕......用VC8编译时代码运行正常,但是在调用时用VC9编译时会抛出"意外异常" a_instances[0].event_more_values.push_back(whatever)
,但访问任何其他成员时.任何见解?
编辑:将memset从更改memset(&a_instances...
为memset(a_instances...
.谢谢你指出Eduard.
EDIT2:删除了ctor的返回类型.谢谢你.
结论:谢谢大家,你证实了我的怀疑.
这是一种广泛接受的C结构初始化方法.
在C++中它不起作用,因为你不能假设vector
内部结构.将其归零非常可能使其处于非法状态,这就是程序崩溃的原因.
他在非POD类类型上使用memset.它是无效的,因为C++只允许它用于最简单的情况:一个类没有用户声明的构造函数,析构函数,没有虚函数和几个限制.它的一系列对象不会改变这一事实.
如果他删除了矢量,他就可以使用memset了.但要注意一点.即使它不是C++,它仍可能对他的编译器有效 - 因为如果标准说某些东西有未定义的行为,实现可以做他们想要的一切 - 包括祝福这样的行为并说出会发生什么.在他的情况下,发生的事情可能是你在它上面应用了memset,它会默默地清除向量的任何成员.其中可能的指针,即指向已分配的内存,现在只包含零,而不知道它.
您可以建议他使用以下内容清除它:
... for(size_t i=0; i < 10; i++) objects[i].clear();
并使用以下内容写清楚:
void clear() { a_object o; o.swap(*this); }
交换只是将o的向量与*this交换,并清除其他变量.交换矢量特别便宜.他当然需要编写一个交换函数,然后交换vector(even_more_values.swap(that.even_more_values)
)和其他变量.