2013-01-18 51 views
1

第一個問題:指針函數參數複製和性能在C++

int num =25; 
int *num1Ptr=# 
int *num2Ptr=NULL; 

void assinNum (int *numPtr){ 

    num2Ptr = numPtr; ////we copy the value (address) of the num1Ptr pointer to num2Ptr 
} 

我的問題是:

使用pointers.For例如很多時候我們傳遞一個對象的引用到另一個通過函數調用:如果這樣的方法被非常頻繁地調用,那麼我們可以期望指針複製的大量開銷?

第二個問題:

在下列情況下,它意味着我們通過複製傳遞numPtr指向num2Ptr指向的內存地址的內存地址的值?如果是的話,那麼它與通過價值相同?

int num =25; 
int *num1Ptr=# 
int *num2Ptr=NULL; 

void assinNum (int *numPtr){ 

    *num2Ptr = *numPtr; ////num2Ptr points to the same value in the memory pointed by numPtr argument. 
} 

更新的第一個問題:

有哪些指向大對象(不是原語)的後果是什麼?

+0

那麼,這是一種僞代碼在這裏...... :) –

回答

3

如果這樣的方法被非常頻繁地調用,我們可以期望指針複製的開銷很大嗎?

指針通常只是一個32位或64位的數量。所以複製一個指針只需要複製一個32位或64位的數量,這在大多數平臺上都很便宜。但是,直接複製int也很便宜,所以在這種情況下,使用指針可能不會帶來太多好處。

另外值得指出的是,在很多情況下,編譯器會通過內聯來優化這個函數。

這是否表示我們將numPtr指向的內存地址中的值複製到num2Ptr指向的內存地址?

理論上,是的。但是,num2Ptr = NULL,所以你的代碼很可能會導致分段錯誤。

那麼它是一樣的傳遞值?

我不確定你指的是什麼,所以很難知道如何回答這個問題!

+0

你能否在你的答案中提到優化器? –

+0

@MooingDuck:你有什麼想法? –

+0

他正在處理一個函數,它的身體是一個單一的任務(在示例代碼中);幾乎每一個編譯器都會內聯它,然後最有可能完全刪除所有的指針位,這使得這個特定的示例沒有意義。你的答案的其餘部分對於一般情況來說是完美的。 –

1

我的問題是:如果這樣的方法被非常頻繁地調用,我們可以期望指針複製的大量開銷嗎?

複製sizeof(int*)?不過,對於函數調用來說,可能會有很大的開銷,尤其是在通過PLT進行調用的情況下。在多線程環境中,這可以間接引入其他開銷。

在下列情況下,是否意味着我們將numPtr指向的內存地址中的值複製到num2Ptr指向的內存地址?

是的。

如果是,那麼它是一樣的傳遞值?

不可以。按整數值傳遞更快主要是因爲按值傳遞不會涉及讀取內存,而是通過寄存器完成。

1

指針複製的成本非常低,但對於指針大小與存儲數據一樣大或更大的原始數據類型來說沒有多大意義。

對於你的第二個問題,你正在應對價值,並將與價值應對相同。

2

如果這樣的方法被非常頻繁地調用,我們可以期望指針複製的開銷很大嗎?

「開銷」意味着您正在比較一些正在進行的可選或虛假工作與實際需要完成的工作量,以實現特定的預期效果。總工作量和最低工作量之間的區別在於開銷。在這種情況下,目前尚不清楚你的基線是什麼。什麼是你會考慮的開銷?將一個指針複製到另一個指針的操作非常小 - 這只是一個32位或64位指定,具體取決於您的目標平臺。這樣的操作不是免費的,但速度非常快。

將numPtr指向的內存地址指向num2Ptr指向的內存地址?

是的,你的代碼顯示覆制由numPtr參考由numPtr2引用的內存在內存中的值。當然,在你的例子中,指針分別引用地址0x00000019和0x00000000,所以在讀取源值時你會崩潰,除非你知道你有可讀的內存;並在寫作時崩潰,除非你知道你也有可寫內存(你可能不會)。請注意您的評論(////num2Ptr points to the same value in the memory pointed by numPtr argument.)不正確。

如果是,那麼它是一樣的傳遞值?

傳遞指針並不像傳遞值。指針是對數據的引用,而不是數據的值。 (當然,指針本身是通過值傳遞的,但是需要對其進行解引用。)由於指針是可寫的,所以可以寫入它,調用者在返回時會看到這種寫入的效果。