外部链接:CWE-665: Improper Initialization
在非 trivially copyable 类型的对象上使用 memcpy
或 memset
。
使用 malloc
为非 non-vacuous initialization 类型的对象分配空间,且没有使用 placement new
运算符和显式的析构函数调用正确处理其生存期。
string s, t;
// ...
memcpy(&s, &t, sizeof(s));
struct node
{
int t;
vector<int> v;
} nodes[114514];
// ...
memset(nodes, 0, sizeof(nodes));
set<int> *s = (set<int> *)malloc(sizeof(*s));
对于变体 1,打开 -Wclass-memaccess
选项 (被 -Wall
包含)。警告信息示例:
t.cc:7:15: 警告:
void* memset(void*, int, size_t)
clearing an object of typeclass std::vector<int>
with no trivial copy-assignment; use assignment or value-initialization instead[-Wclass-memaccess]
对于变体 2,使用文本编辑器在代码中查找 malloc
。
如果你不清楚你在初始化什么东西,就不要使用 memset
。对于非数组 (没有手写构造函数的结构体,以及 STL 容器),建议的初始化方法如下:
struct node
{
int t;
vector<int> v;
} nodes[114514], a_node;
vector<node> a_vector;
// ...
a_node = {};
a_vector = {};
对于一维数组,建议的初始化方法如下:
template <class T, size_t N>
void clear(T (&a)[N], size_t n = N)
{
fill(a, a + n, T{});
}
vector<int> a[114514];
int main()
{
clear(a); // initialize the entire array
clear(a, 10); // initialize part of the array
}
对于 memcpy
同理,可以直接用赋值操作 (非数组) 或 std::copy
(数组) 完成复制操作。
为了提高代码可读性,可以用 std::array
代替数组 (这样就能直接用 =
来初始化或者复制)。
注:由于 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100466 ,现在不行
除了一些极其特殊的情况,永远 (包括退役以后实际写工程) 不要在 C++ 代码中使用 malloc
/free
,总是使用 new
/delete
替代它们。