2016-11-28 46 views
0

幾個小時前我剛剛問過一個問題,我一直對答案中指出的某些事情感到困惑(arrays using pointers in c++: segmentation fault when accessing the returned array)。有些人對我的新問題做出了一些負面反應,所以我翻閱了關於指針的書,這對我沒有多大幫助。所以,我又來了。通過引用使用指針傳遞數組引起的混淆

在上一個問題中,我有一個函數void builder(int aSize1, int aSize2, int aSize3, int*** frequencies),我認爲它會爲傳入的int*** frequencies參數的3d數組動態分配內存並初始化它。然而,我被告知只有一個副本將被傳遞到函數,我會被分配併爲副本不是原來只是初始化。因此,他們建議我使用參考,將函數原型渲染爲void builder(int aSize1, int aSize2, int aSize3, int***& frequencies)。我回想起,就在昨天,當我第一次偶然發現了使用指針傳遞引用的概念時,我們也可以操縱指針的數據。到機智,

void change_what_this_points_to(int* a) 
{ 
    *a = 42; 
} 

這個函數改變被送入的功能的指針的值。

所以,我的問題是,爲什麼前者通過副本而後者通過實際交易?除了人們有更多的星號之外,我沒有看到這兩種功能之間有太大的區別。

任何幫助,將不勝感激。謝謝!

+0

它們表示您傳遞*指針*的副本,而不是它指向的內容。 – juanchopanza

+0

在C++語言編程時,不要亂用原始指針。從上個世紀就是如此。請走向現代。 –

+0

@πάνταῥεῖ我在最後一個問題中有類似的評論,我會作出相應的迴應。我對C++和指針的概念很陌生,並且想了解底層的東西。恕我直言,我沒有看到在這方面的傷害:) – Astaboom

回答

1

此功能

void change_what_this_points_to(int* a) 
{ 
    *a = 42; 
} 

不會改變指針本身。它改變指針指向的整數對象。

如果你想改變指針本身,你應該寫函數以下任一方式

void change_what_this_points_to(int * &a) 
{ 
    a = new int(42); 
} 

或通過以下方式

void change_what_this_points_to(int **a) 
{ 
    *a = new int(42); 
} 

並返回到你的函數應聲明它要麼喜歡

void builder(int aSize1, int aSize2, int aSize3, int*** &frequencies); 

或類似

void builder(int aSize1, int aSize2, int aSize3, int**** frequencies); 
2

雖然另一個答案完美地說,我只是想我會加我兩分錢,以防萬一它有幫助。將指針看作是內存中的地址。你將這個地址傳遞給一個函數,並且函數在那裏寫入一些東西。然後,在調用函數之後,可以查看內存中的相同位置,並查看其中的值。

因此,讓我們假設你有下面的代碼:

void SetValue(int *a){ *a = 10;} 
void DoWork() 
{ 
    int a; 
    SetValue(&a); 
} 

執行setValue函數作爲一個參數指針爲int,或者我們會想它,地址在內存中一個int存儲。該函數然後簡單地將數字10寫入傳入的地址。

DoWork方法然後爲int創建內存並將該內存的地址傳遞給該函數。因此,DoWork返回存儲「a」的內存的值爲10.聽起來你已經從你的問題中得到了這一點,但是爲了以防萬一,我想從這裏開始。

現在讓我們假裝你想要一個函數爲你分配內存。你真正要求函數做的是分配內存並告訴我內存在哪裏。所以你可以用指針返回值,即

int* AllocateMemoryForMe() 
{ 
    return new int(); //Creates memory for an int, let's pretend it's at location 0x100 
} 
void DoWork() 
{ 
    int* a = NULL; // a has a value of 0x00 
    a = AllocateMemoryForMe(); //a will now have the value of 0x100 
    *a = 10; //We now write 10 to memory location 0x100 
} 

或者你可以使用指針來做到這一點。如果你這樣做,你實際上必須做的是將函數傳入內存中的一個位置,以便將分配內存的地址寫入,所以指向一個指針。因此,當函數返回時,您可以查看此地址並查看新創建的內存的地址。例如:

void AllocateMemoryForMe(int** x) 
{ 
    *x = new int(); //allocates memory for an int, let's pretend it's at memory location 0x200 
} 
void DoWork() 
{ 
    int** a = new int*(); //Creates memory for an int pointer. Let's pretend it allocates memory at location 0x100. 
    AllocateMemoryForMe(a); //pass memory location 0x100 to the function. 
    //Right now the address of a is still 0x100 but the data at the memory location is 0x200. This is the address of the int we want to write to. 
    **a = 10; //This will now write 10 to the memory location allocated by the AllocateMemoryForMe() function. 

}