亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么對于不能TriviallyCopyable的對象,std :: memcpy的行為將無法定義?

為什么對于不能TriviallyCopyable的對象,std :: memcpy的行為將無法定義?

來自http://en.cppreference.com/w/cpp/string/byte/memcpy:如果對象不是TriviallyCopyable(例如標量,數組,C兼容結構),則該行為是不確定的。在我的工作中,std::memcpy很長時間以來,我們一直使用以下方法按位交換不可TriviallyCopyable的對象:void swapMemory(Entity* ePtr1, Entity* ePtr2){   static const int size = sizeof(Entity);    char swapBuffer[size];   memcpy(swapBuffer, ePtr1, size);   memcpy(ePtr1, ePtr2, size);   memcpy(ePtr2, swapBuffer, size);}從來沒有任何問題。我了解濫用std::memcpy非TriviallyCopyable對象并導致下游未定義行為是微不足道的。但是,我的問題是:std::memcpy與非TriviallyCopyable對象一起使用時,為什么自身的行為不確定?為什么標準認為有必要對此加以說明?更新針對此帖子和該帖子的答案,已修改了http://en.cppreference.com/w/cpp/string/byte/memcpy的內容。當前的描述是:如果對象不是TriviallyCopyable(例如標量,數組,與C兼容的結構),則除非程序不依賴于目標對象的析構函數的影響(不是由memcpy)運行,否則行為是不確定的。目標對象(以結束,但未以開頭memcpy)是通過其他某種方式(例如,新放置)來啟動的。
查看完整描述

3 回答

?
湖上湖

TA貢獻2003條經驗 獲得超2個贊

構造一個memcpy基于該類swap中斷的類很容易:


struct X {

    int x;

    int* px; // invariant: always points to x

    X() : x(), px(&x) {}

    X(X const& b) : x(b.x), px(&x) {}

    X& operator=(X const& b) { x = b.x; return *this; }

};

memcpy這樣的對象破壞了不變性。


GNU C ++ 11 std::string正是使用短字符串來做到這一點。


這類似于標準文件和字符串流的實現方式。最終從中獲得流,std::basic_ios其中包含指向的指針std::basic_streambuf。流還包含作為該指針指向的成員(或基類子對象)的特定緩沖區std::basic_ios。


查看完整回答
反對 回復 2019-10-30
?
慕絲7291255

TA貢獻1859條經驗 獲得超6個贊

因為標準是這樣說的。

編譯器可能會假定非TriviallyCopyable類型僅通過其復制/移動構造函數/賦值運算符進行復制。這可能是出于優化目的(如果某些數據是私有的,則可以將其設置推遲到復制/移動發生之前)。

編譯器甚至可以自由地接聽您的memcpy電話,使其無所事事,或格式化硬盤。為什么?因為標準是這樣說的。而且無所事事肯定比移動位快得多,那么為什么不優化您的程序memcpy來使它同樣有效呢?

現在,在實踐中,當您只對不需要的類型的位進行四處查找時,可能會發生許多問題。虛擬功能表可能未正確設置。用于檢測泄漏的儀器可能未正確安裝。身份包括其位置的對象將完全被您的代碼弄亂。

真正有趣的部分是,對于編譯器可復制的類型,using std::swap; swap(*ePtr1, *ePtr2);應該可以將其編譯memcpy為,對于其他類型,則應定義行為。如果編譯器可以證明副本只是被復制的位,則可以將其更改為memcpy。而且,如果您可以編寫更優化的代碼swap,則可以在相關對象的名稱空間中執行。


查看完整回答
反對 回復 2019-10-30
  • 3 回答
  • 0 關注
  • 465 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號