2013-05-12 158 views
5

計劃:指針和C內存分配

int x; 
int *y; 
int **z; 

z = (int **) malloc (sizeof(int *)); 
y = (int *) malloc (sizeof(int)); 
x = 1; 
*z = &x; 
*y = x; 
. 
. 
. 

問題: 之間有什麼區別:從我瞭解* Z點x和* Y點的地址

*z = &x; 
*y = x; 

到x,但是* y指向x不需要x的地址?我真的不明白這兩個變量是怎麼回事。

編輯: 我也想知道我們什麼時候知道什麼時候在堆棧或堆上分配變量?

  • 爲什麼x,y和z分配在堆棧上?
  • 爲什麼* y,** y,* z,** z分配在堆上?

最後,改變* z,改變** z?

+0

「根據我的理解......」你誤解了。 z和y仍然指向您分配它們時指向的任何內存塊。 – 2013-05-12 14:20:41

+0

您不應該在C中使用'malloc()'的返回值。這將有助於識別沒有原型的錯誤。 – jxh 2013-05-12 14:22:09

+1

首先,你需要明白,最後兩條陳述完全不同。第一個將x的*地址*賦給任意z指向的元素,而第二個賦予x的*值*給y指向的任何東西。如果您指定一個值,則原件和副本將變爲「斷開連接」,以便更改一個不會更改另一個值。但是,當你只使用地址,然後兩個在臀部加入 - 改變一個,你改變另一個。 – 2013-05-12 14:27:44

回答

6

z是一個指向指針的指針(它通常指向一個動態分配的指針數組)。

y是指向int的指針。同樣,通常它會指向一個動態分配的數組int s。

因此,*z = &x;正在設置指針z指向指向x。即,z指向一個指針,該指針又指向x

*y = x;走的是x並分配它到int指向y

對於這樣的事情,圖片通常是有幫助的。所以,我們的基本定義,在此給我們:

enter image description here

的,我們做的事:

z = (int **) malloc (sizeof(int *)); 
y = (int *) malloc (sizeof(int)); 

這給了我們這樣的:

enter image description here

然後我們這樣做:

*z = &x; 
*y = x; 

這給了我們這樣的:

enter image description here

在所有這些,虛線表示從一個地方到另一個地方的指針,而實線表示從複製一個地方到另一個地方的值。

我們可以考慮他們之間的長期差異。例如,考慮在上述所有分配之後添加x=2;會發生什麼。

在這種情況下,*y仍然將等於1,因爲我們從x複製的價值1*y**z將等於2,因爲它只是指向x - x中的任何更改都將反映在**z中。

2

此行存儲可變x的地址在存儲器指向z

*z = &x; 

此行存儲值的x到內存通過y指出:

*y = x; 

這兩個賦值語句是不相關的:第二個賦值語句是wh第一個不是。如果您更改x的值,然後檢索**z,您將看到新的值x;但是,檢索*y會使您返回舊值x(即1)。

+0

謝謝!這非常有道理! – 2013-05-12 14:34:27

0

兩個分配之間的區別在於,第一(* z)爲地址類型爲指針的值,其中所述第二(* y)爲的值的地址的分配指向的分配 由y。

它們都將值分配給它們指向的內存。

不同之處在於寫入該分配內存的值的類型。 第一個值是一個地址,這就是爲什麼它將x的地址作爲值。 第二個值是一個整數,因此得到x的值。 y,y不指向x。

* y不指向x。

它指向x值被複制到的未知存儲位置。 它將x的值分配給爲y分配的內存空間。