簡體   English   中英

為什么同一指針有不同的地址

[英]Why does same pointer has different addresses

class A{};

void Foo(A *p)
{ 
 std::cout << &p << std::endl; 
 std::cout << p << std::endl; 
}

int main()
{
 A *p = new A();
 std::cout << &p << std::endl;
 std::cout << p << std::endl;
 Foo(p);
}

上述程序為p打印相同的值,但為&p打印不同的地址。 有人可以解釋一下原因嗎?

上面的程序打印“p”的相同值

這是因為一個p是另一個的副本,因此它們都具有相同的值。 指針的值是存儲對象的存儲器地址,因此具有相同的值意味着指向同一對象。

函數參數是傳遞給函數的對象的副本。

但“&p”的地址不同。 有人可以解釋一下原因嗎?

這里的每個p都是一個單獨的變量和一個單獨的對象†† 兩個對象同時存在。 C ++標准指定每個當前存在的對象具有唯一的地址††† ,因此每個p必須具有唯一的地址。

一元運算符&是運算符的地址,它返回存儲操作數的存儲器地址。


除非該函數參數是參考。 在這種情況下,引用綁定到傳遞的對象。 p參數不是參考。

††指針本身就是物體。 存儲指針的存儲器地址與作為指向對象的存儲器地址的值的存儲器地址是分開的。

†††子對象有例外,但這些例外與此無關。

void Foo(A *p)
{ 
 std::cout << &p << std::endl; 
 std::cout << p << std::endl; 
}

當你把東西傳遞給Foo() ,某些東西被復制到p 。因此,實際參數(傳遞的東西)與形式參數(這里是p )不同,盡管它們將保持相同的值。 Foo()內部, &p將打印此形式參數的地址,而不是傳遞的實際參數的地址。

並且由於形式和實際參數保持相同的值,因此p打印相同的值。

operator &是返回變量的地址

它們是差異變量A *aFoo(A *a)但它們指向相同的地址。 它通常有不同的地址。

這是堆棧和堆的很好的描述。 堆棧和堆的內容和位置是什么?

其他人提到的簡短答案是:

p指向從堆分配的A的已分配實例。 它是在代碼中使用運算符“new”創建的。

&p指向p本身占用的內存。 就像A類占用內存(使用'new'運算符從堆分配)一樣,p占用內存(從堆棧分配,因為它是一個局部變量)。

由於復制構造函數,此事件發生。

復制構造函數是一個構造函數,它通過使用先前創建的同一類的對象初始化它來創建對象。 復制構造函數用於 -

- 從同一類型的另一個對象初始化一個對象。

- 復制對象以將其作為參數傳遞給函數。 (這是指你的問題)

- 復制對象以從函數返回它。

p是包含堆中對象地址的局部變量。 和&p是堆棧中p的地址。 當我們將p傳遞給Foo()時,由於復制構造函數編譯器將p復制到新的局部變量,因此我們有2個指針,它們都指向堆內存中的相同位置。 它們是原始p( 實際參數 ),第二個是Foo()方法中的未命名局部變量( 形式參數 ),它是由復制構造函數構建的。

你也可以在下面的圖像中看到p和p之間的區別。

p vs&p

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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