为什么或为什么不在C ++中使用memset?

时间:2014-10-04 18:40:50

标签: c++ memory memory-management memset

我在程序中有很多memset,我必须维护。在现代C ++中使用memset是一个好习惯吗?

为什么不呢?

如果没有,memset会优先考虑什么?

2 个答案:

答案 0 :(得分:7)

90%的时间你应该使用std::fill而不是memset。这是因为std::fill可以正确地使用类,并且在将非字节类型的数组设置为非零值时也可以。例如,您可以将整数数组memset设置为0,但不能将整数数组memset设置为0x12345678。使用std::fill即可。

好的编译器可以在适当的情况下优化std::fill到memset。如果他们不这样做,任何对性能的影响都可以忽略不计。

当memset更快时使用std::fill并不危险。使用memset应该使用std::fill是危险的。默认为std::fill

同样适用于memcpystd::copy

答案 1 :(得分:2)

显然,memset()只能使用标准布局类型。即使是那些价值观也不一定是可以预测的。例如,不能保证空指针将具有所有空字节,尽管我不知道任何系统,其中空指针不使用所有空字节。

显而易见的替代方法是使用构造函数。对于使用构造函数的非标准布局类型,显然是正确初始化对象的唯一方法。即使对于POD类型,也会生成构造函数,这些构造函数适用于零初始化。也就是说,构造函数通常不会初始化任何填充,而memset()将初始化填充。此外,调用构造函数会产生开销:如果需要初始化许多对象,则使用memset()可能更有效。在我写的代码中,我并没有真正遇到需要批量初始化许多对象的情况,即性能参数对我来说并不存在。

就个人而言,我不会使用memset()初始化对象,而是使用generate构造函数。要初始化对象序列,我要么依赖容器来完成工作,要么正确使用fill()uninitialized_fill()。在我经常使用memset()初始化对象的少数情况下,它总是错误的,即我会考虑使用memset()警告标志,尽管它可以正确使用。

因此,总而言之,我认为这是一种不好的做法,而是使用一致的方法来使用合适的构造函数,可能来自容器内,或者在必要时(例如,当实现类似于std::vector<T>的类似的算法时如果性能表明它实际上有所不同并且正在初始化的对象是标准布局类型,可能memset()可能是一个选择,但我不知道,因为我从未遇到过我最终必须初始化的情况许多标准布局(或POD)类型。