2014-10-04 133 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

相關問題