CWARN.MEM.NONPOD
内存操作例程应用于非 POD 对象
低级内存操作例程(memset、bzero、memcpy)不得用于初始化非 POD(纯旧数据)类型的对象。这种对象应通过其构造函数进行初始化。
漏洞与风险
如果一个对象为非 POD 对象,它通常包含不同于纯数据的信息。直接写入被这种对象占用的内存很可能破坏其内部的内存表示形式。尤其,该对象本身的虚拟表或其成员之一可能丢失,因此,调用虚拟成员函数的尝试可能导致故障。如果使用这些成员,直接重写引用成员也将导致失败。
示例
复制
struct XXX {
int x, y;
};
struct A
{
int a;
vector<XXX> b;
};
void foo() {
struct A aaa;
memset(&aaa, 0, sizeof(aaa)); // DEFECT
struct A *paaa = (struct A *)malloc(sizeof(struct A));
memset(paaa, 0, sizeof(struct A)); // DEFECT
struct XXX xxx;
memset(&xxx, 0, sizeof(struct XXX)); // OK - struct XXX is POD
}
为修正此示例,移除错误的 memset 并向结构 A 添加一个构造函数。如果使用 malloc 或未调用构造函数的其他分配器为对象分配内存,请使用位置 new:
复制
struct XXX {
int x, y;
};
struct A
{
int a;
vector<XXX> b;
A() : a(0) {}
};
void foo() {
struct A aaa;
void *paaa_memory = malloc(sizeof(struct A));
struct A *paaa = new (paaa_memory) A;
struct XXX xxx;
memset(&xxx, 0, sizeof(struct XXX));
}