[英]How does memcpy work on pointers to arrays?
我像這樣初始化2個數組:
x = (double*) malloc(sizeof(double)*n);
xPlus1 = (double*) malloc(sizeof(double)*n);
首先,我不確定確切是什么x或xPlus1,是指向充滿雙打的數組的指針,還是充滿指向雙打的指針的數組? :/
該問題的答案可能會影響這一點,但是如果執行這些各種操作,我將無法完成我想要的操作,這僅僅是將xPlus1中的值復制到x中。 xPlus1和x的每個索引確實具有不同的值,因為在簡單的for循環之后進行打印可獲得所需的效果:
for (int i = 0; i < n; i++) {
x[i] = xPlus1[i];
}
但是使用...
memcpy(x, xPlus1, sizeof(x));
memcpy(x, &xPlus1, sizeof(x));
如果我在同一函數中的任何一個之后訪問x,則x保持不變,保留其舊值。
memcpy(&x, &xPlus1, sizeof(x));
我相信這會使x和xPlus1通過我得到的輸出指向相同的內存位置。 這是因為如果在此副本之后修改x或xPlus1,則如果我同時打印兩個數組,則兩個值都會更改。
memcpy(&x, xPlus1, sizeof(x));
死,異常:MPITemplate.exe中0x011D5626處未處理的異常:0xC0000005:訪問沖突寫入位置0x00000000。
函數中的&符通常表示按引用傳遞,給與memcpy時如何顯示引用,如果最后要寫相同的塊,這會有什么區別?
如果有人可以詳細告訴我這些操作的進展,我將不勝感激,因為我可以擺弄它的工作原理,但我寧願了解進行這些調用時的實際情況。
謝謝,
麥克風
x
和xPlus1
都應為double*
類型。 它們是n
雙精度數組的指針。
因此,當您執行此操作時:
memcpy(x, xPlus1, sizeof(x));
由於x
只是double*
,因此僅復制sizeof(double*)
個字節...也就是說8。您要做的是:
memcpy(x, xPlus1, n * sizeof(*x));
因為*x
的類型是double
,所以n * sizeof(*x)
將是xPlus1
擁有的總內存字節: n
double
s。
您忽略了聲明。
添加類型,
double* x = (double*) malloc(sizeof(double)*n);
更清楚地表明x
是指向double
的指針。
在這種情況下,雙精度點x
指向n
雙精度點數組中的第一個元素。
像這樣:
(------- n doubles -----)
___________________________
x ===>| | | | | | | | | | | | | |
---------------------------
&x
將為您提供變量x
本身的地址 。 這與變量x
包含的地址非常不同。
(如果int x = 1;
, &x
很可能不是1。)
memcpy
需要兩個指針,一個指向目標,一個指向源,以及要復制的內存大小。
但是sizeof(x)
不能給您分配的數組的大小。 它的大小為x
,它是一個指針。
(大小以sizeof(char)
倍數度量,其定義為1,在大多數現代機器上, sizeof(double*)
將為4(32位)或8(64位)。因此,您要復制32或64位。)
如果要復制整個內容,則size參數應該與傳遞給malloc
大小相同。
指針應該是從malloc
返回的指針,因為這些是您要復制的內存塊。
所以,
memcpy(x, xPlus1, sizeof(double) * n);
應該能按預期工作。
我像這樣初始化2個數組:
不,你不是。 您沒有顯示x
和xPlus1
定義,但是如果它們是如下數組:
double x[10];
您的代碼無法編譯。 因此,假設您的代碼編譯x
和xPlus1
是double的指針 。 它們很接近,但不一樣。
首先,我不確定確切是什么x或xPlus1,是指向充滿雙打的數組的指針,還是充滿指向雙打的指針的數組? :/
同樣,您應該發布它們的定義,然后您的問題將變得毫無意義。 它們是指針,您分配給它們的任何內容都不會改變這一事實。 因此,它們是保存內存塊大小為sizeof(double) * n
地址的指針。 內存中的內容取決於您,您可以將其視為double數組,或者其他大小小於或等於sizeof(double) * n
。
但是使用...
memcpy(x, xPlus1, sizeof(x));
memcpy(x, &xPlus1, sizeof(x));
因此,第一行代碼從xPlus1
指向的內存到x
指向的內存復制sizeof(double *)可能是8個字節,即一個double(在64位平台上sizeof(double *)== sizeof(double)是一致的)。 因此,您基本上復制了一個元素,並且與之相同(如果您在32位平台上,則只需復制double的一半):
x[0] = xPlus1[0];
第二行復制了內存,其中指針xPlus1
指向x
指向的內存塊。 因此,您將double *
復制到double
x [0]並沒有多大意義:
x[0] = (double) xPlus1;
這段代碼:
memcpy(&x, &xPlus1, sizeof(x));
基本上做到了這一點(只是令人費解的方式):
x = xPlus1;
以下代碼:
memcpy(&x, xPlus1, sizeof(x));
等效於此:
x = (double *)xPlus1[0];
這使得x
指針具有導致異常的垃圾地址。
因此,您的實際代碼應為:
memcpy( x, xPlus1, sizeof( double ) * n );
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.