簡體   English   中英

memcpy如何處理指向數組的指針?

[英]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時如何顯示引用,如果最后要寫相同的塊,這會有什么區別?

如果有人可以詳細告訴我這些操作的進展,我將不勝感激,因為我可以擺弄它的工作原理,但我寧願了解進行這些調用時的實際情況。

謝謝,

麥克風

xxPlus1都應為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個數組:

不,你不是。 您沒有顯示xxPlus1定義,但是如果它們是如下數組:

double x[10];

您的代碼無法編譯。 因此,假設您的代碼編譯xxPlus1是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.

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