簡體   English   中英

使用賦值而不是memcpy()在C中復制結構

[英]Copying structure in C with assignment instead of memcpy()

直到最近,我才看到用memcpy()復制結構字段。 在類和在線指令中,將一個結構的內容復制到另一個結構中通常看起來像

struct block *b0 = malloc(sizeof(struct block));
struct block *b1 = malloc(sizeof(struct block));
/* populate fields in *b0 */
memcpy(b1, b0, sizeof *b1); /* copy contents of b0 into b1 */
/* free b0, b1 */

但是,也可以通過替換memcpy()的簡單賦值來完成此任務。

*b1 = *b0; /* dereferenced struct assignment */

有沒有充分的理由說明為什么它沒有被廣泛使用(至少在我有限的經驗中)? 這兩個方法 - 賦值和memcpy()等價,還是有一些令人信服的理由一般使用memcpy()

兩種方法都是等效的,並執行淺拷貝 這意味着復制了結構本身,但不復制結構引用的任何內容。

至於為什么memcpy更受歡迎,我不確定。 較舊版本的C不支持結構分配( 雖然它早在1978年就是常見的擴展 ),因此memcpy樣式可能會成為制作更多可移植代碼的方式嗎? 在任何情況下,PC編譯器都廣泛支持結構分配,並且使用memcpy更容易出錯(如果大小錯誤,可能會發生壞事),因此最好盡可能使用結構分配。

但是,只有memcpy有效。 例如:

  • 如果要將結構復制到未對齊的緩沖區或從未對齊的緩沖區復制 - 例如,要保存/加載到磁盤或從網絡上發送/接收 - 您需要使用memcpy ,因為結構分配需要正確對齊源和目標。
  • 如果要在結構之后打包附加信息(可能使用零元素數組) ,則需要使用memcpy ,並將此附加信息計入大小字段。
  • 如果要復制結構數組,那么執行單個memcpy 可能更有效,而不是單獨循環和復制結構。 然后,它可能不會。 很難說, memcpy實現的性能特征不同。
  • 某些嵌入式編譯器可能不支持結構分配。 當然,有問題的編譯器可能還不支持其他更重要的事情。

還要注意,雖然在C memcpy和結構賦值中通常是等價的,但在C ++中memcpy和結構賦值並不等價。 在一般的C ++中,最好避免使用memcpy結構,因為結構賦值可以並且經常被重載以執行其他操作,例如深層復制或引用計數管理。

這可能不是您尋找的確切答案。

我解釋了我遇到的情景。

當我們使用memcpy() ,它會逐字節地復制到目標。 所以不用擔心ARM架構中的數據對齊。 如果使用=運算符,並且任何一個地址未與4字節對齊,則會出現對齊錯誤。

來自Arm站點:

指向目標位置的指針,該指針位於寫入的最后一個字節之外一個字節。 這使得寫入過程的繼續with perfect alignment of bytes用於字符串串聯內存塊with perfect alignment of bytes

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0175k/Cihbbjge.html

我正在復活這個老問題,因為答案並沒有解釋為什么 memcpy實際上是首選。

memcpy是首選,因為它清楚地表明程序員想要復制內容而不是簡單的指針。

在下面的示例中,兩個賦值有兩個非常不同的東西:

struct Type *s1,*s2;
*s1=*s2;
s1=s2;

無意中使用一個而不是另一個可能會產生災難性的后果。 編譯器不會抱怨。 除非在使用未初始化指針時程序崩潰,否則錯誤很長時間都會被忽視並產生奇怪的副作用。

將其寫成以下之一:

memcpy(s1,s2,sizeof(*s1));
memcpy(s1,s2,sizeof(*s2));
memcpy(s1,s2,sizeof(struct Type));

讓讀者知道目的是復制內容(以類型安全和邊界檢查為代價)。

有些編譯器(例如gcc)甚至會在遇到類似以下內容時發出有關sizeof的警告:

memcpy(s1,s2,sizeof(s1));

有些人更喜歡memcpy,因為這是他們學到的東西,他們從來沒有想過他們可以做一個任務(在古代,不允許任務,但很久以前)。 沒有對齊問題需要擔心,因為malloc()分配的內存總是正確對齊。 而且由於編譯器可以將這個賦值簡單地轉換為memcpy調用,因此它永遠不會比memcpy更慢或更多代碼。 當然,嵌入式系統中存在嚴重過時的編譯器。

在嵌入式平台上工作的人更願意使用memcopy而不是直接分配結構。 主要是當您處理嵌入式平台時,某些編譯器不支持直接結構分配,因為您需要使用memcopy。 如果您正在使用PC,那么在任何一種情況下都沒有問題,兩者都是有效的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM