2011-03-15 98 views
5

可以嗎?memcpy部分複製

char buf[] = { 0, 1, 2 }; 
memcpy(buf, buf + 1, 2); 

是否有更大的數據類型有什麼區別?我知道我可以使用memmove(),但我只是好奇。

+0

-1:當你嘗試時發生了什麼? – pmg 2011-03-15 12:03:17

+3

+1,因爲我不同意pmg的-1。 「當你在標準中查看時發生了什麼?」,也許,但是在嘗試這種事情時存在真正的風險,你可能會嘗試並且「有效」,結果爲{1,2,2} '在緩衝區中。那麼建議有什麼用處呢?它是否會在下週仍然有效,或者當您打開優化或客戶計算機時仍然有效? – 2011-03-15 12:37:49

+0

@Steve Jessop:我同意。 OP的例子將(可能)工作,這取決於'memcpy'的特定目標平臺實現,但這並不是一個好主意! – GrahamS 2011-03-15 12:42:00

回答

12

當輸入和輸出重疊時,memcpy的效果未定義。你應該使用memmove

5

不好。當源和目標重疊時,您必須必須使用memmove

可能使用memcpy,這取決於你的編譯器的實現,但這不是你應該依賴的東西!


一個典型的幼稚的做法是逐字節副本(UINT8)是這樣的:

typedef unsigned char uint8; 

void * memcpy (void * destination, const void * source, size_t num) 
{ 
    const uint8* pSrc = (const uint8*)source; 
    const uint8* const pSrcEnd = pSrc + num; 
    uint8* pDst = (uint8*)destination; 

    while (pSrc != pSrcEnd) 
     *(pDst++) = *(pSrc++); 

    return destination; 
} 

這將工作沒關係你memcpy(buf, buf + 1, 2),但少爲人與memcpy(buf + 1, buf, 2)

3

如果內存區域重疊,行爲是不確定的,所以這是不好的。

1

這是不確定的行爲,但我已經用它像這樣,

char buf[] = {0, 1, 2, 3); 
memcpy(buf, buf+2, 2); 

在目的地的終點是小於源的起點。 你應該仍然使用memmove來確保...

+0

GNU C庫已經轉換了幾次memcpy的實現。有時甚至i686與i386與x86_64不同。 – 2012-04-11 22:19:28