2009年1月8日 星期四

[c#] memory copy

以下文章我本來只貼在BBS,蘇cent請我貼在這裡,如果有錯請大家鞭小力一點。

c# 的 memory copy method 有三種常見的方式: Copy, CopyTo, Clone。而觀念主要分為兩大類,一類為 deep copy,一類為shallow copy。c# 的陣列或物件預設通通是「reference type」,所謂的 deep copy,就是重製了一個新的物件,然後將值通通搬過去。shallow copy則是建立一個新的reference,但指向的還是原本的物件實體。

http://www.discussweb.com/c-programming/966-copyto-clone.html
因此,這條thread講的東西便大有問題!其實是因為 MSDN 上的定義有講跟沒講一樣:

Copy    將一個 Array 中某範圍的元素複製到另一個 Array,並在必要時執行型別轉換和 Boxing。
CopyTo  將目前一維 Array 的所有元素複製到指定的一維 Array。
Clone   建立 Array 的表層複本 (Shallow Copy)。

可是事實上 ...下面這篇才是對的。
http://www.geekinterview.com/question_details/5653

做個總結:CopyTo, Clone是shallow copy,Copy是deep copy。

補充一個例子,這例子是從義崧二胡合成的程式節錄下來的。

image

這裡的 vis 是用 new 所產生,所以很直覺會以為 vis 會指向新的物件,然後再透過下一行的 CopyTo 將 gcdSums 的資料複製過來。問題出在,整段 code 中有出現 vis 變數的就只有這段了。。。(謎)

2 則留言:

AL 提到...

gcdSums記錄的是VoteInfo的reference.
所以gcdSums.Values.CopyTo(vis,0);是把許多VoteInfo的reference copy到vis裡,所以gcdSums.Values 和 vis[i]指到的是同塊記憶體;所以對vis[i]做存取也同時改到gcdSums.Values的值。

87showmin 提到...

原來如此,感謝長的提示。只是我上面的解釋依舊是正確的嗎?因為如果gcdSums.Values存的是reference,那是用deep copy或shallow copy應該都一樣吧。