2014-10-04 105 views
2

我有很多memset在我必须维护的程序中。在现代C++中使用memset是否是一个好习惯?为什么或者为什么不在C++中使用memset?

为什么?为什么不?

如果不是,memset应该更喜欢什么?

+12

是的,不,也许给我们展示一下它的使用方式 – NPE 2014-10-04 18:41:46

+0

不需要使用'std :: fill',它可以在可能的情况下优化为memset,并且可以在类中使用。 – 2014-10-04 18:42:31

+1

如果您将数据类型定义为类,则构造函数可能会负责初始化。但是,如果你有待处理的原始内存字节,那么memset是选择 – 2014-10-04 18:42:57

回答

7

90%的时间应该使用std::fill而不是memset。这是因为std::fill可以在类中正常工作,并且在将非字节类型的数组设置为非零值时也可以工作。例如,可以将int数组memset为0,但不能将int数组memset memset为0x12345678。随着std::fill你可以。

良好的编译器可以将std::fill优化为适合的memset。在没有的情况下,任何性能影响都可能忽略不计。使用std::fill当memset更快时不会危险。使用memset应该已经使用std::fill是危险的。默认为std::fill

同上,用于memcpystd::copy

+2

如果你downvote请留下解释原因的评论。否则没有人学到任何东西。 – 2014-10-04 19:04:06

+1

你应该怎么做另外10%的时间?使用'memset'。如果是的话,你应该使用memset而不是'std :: fill'? – 2015-04-17 08:45:27

+0

@Zboson我不知道,我只是把它放在我的背后,以防有人提出一些奇怪的边缘情况,其中memset优于填充。 – 2015-04-18 03:19:16

2

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

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

个人而言,我不会使用memset()初始化对象,而是使用生成构造函数。要初始化一系列对象,我要么依靠容器来完成这项工作,要么依靠合适的使用fill()uninitialized_fill()。在少数情况下,我经常使用memset()来初始化对象,这总是错误的,也就是说,尽管它可以正确使用,但我会考虑使用memset()警告标志。总之,我认为这是不好的做法,而是使用一致的方法来使用合适的构造函数,可能来自容器内,或者在必要时(例如,当实现类似于std::vector<T>的合适算法时)。如果性能显示它实际上是有区别的,并且初始化的对象是标准布局类型可能memset()可能是一个选择,但我不知道,因为我从来没有在这种情况下,我最终不得不初始化大量的标准布局(或POD )类型

+4

来自7秒内看downvoted这个答案的用户的任何评论?你真的读得那么快吗? – 2014-10-04 19:01:45

+0

我意识到我没有给出所需的答案(“'memset()'很好 - 一起去吧”),但我会对downvote的原因感兴趣。 – 2014-10-04 19:02:37

+0

您很好地讨论了构建对象的情况,但是如果您有一些现有对象并希望为它们提供新的值,那么情况如何? – 2014-10-04 19:03:11

相关问题