2009-08-11 64 views

回答

11

通過值將指針傳遞給函數。實質上,這意味着指針值(但不是指針!)被複制。你修改的只是原始指針的副本。

有兩個解決方案,無論是使用間接的附加層:

  1. 要麼使用的引用:

    void f(int*& a) { 
        a = new int[4]; 
    } 
    
  2. 或者你在一個指針到指針傳遞(以下傳統的輸出參數如您的情況):

    void f(int** pa) { 
        *pa = new int[4]; 
    } 
    

    並調用函數li柯本:

    f(&a); 
    

就個人而言,我不喜歡這兩種風格:參數是功能輸入,輸出應該是返回值進行處理。到目前爲止,我還沒有看到在C++中偏離這個規則的令人信服的理由。所以,我的建議是:改用下面的代碼。

int* create_array() { 
    return new int[4]; 
} 
+0

爲什麼你會在C++(也許在C)中寫'f(int ** pa)'。現在你需要檢查NULL。你可以重新安排,以便更安全的技術在頂部(並添加NULL檢查)。 – 2009-08-11 16:15:13

+3

@Martin:'NULL'檢查根本沒有幫助,因爲你在C++中真正需要的是一個指針合法性檢查 - 它不存在。所以不行,代碼是完整的,雖然很脆弱,但是調用者的責任是確保指針是正確的,我同意這不是你想寫的代碼。 *但是,實際上有些人會看到這種風格的好處,因爲它在調用者的網站上顯而易見*該函數修改了參數的值。這在參考文獻中並不明顯。就我個人而言,我不同意 - 但是,我永遠不會使用'out'參數。 – 2009-08-11 17:40:52

6

您可以通過值將參數傳遞給foo。更改爲

foo(int*& a) 
4

您正在傳遞價值。

您需要通過按引用:

void Something::foo(int* &a) 
{ 
    a = new int[4]; 
} 

也許是更清楚這樣做:

int* Something::foo() 
{ 
    int* a = new int[4]; 
    return a; 
} 

int* b = foo(); 

確保當你返回一個指針(或更新參考)由一種方法分配的內存,它清楚何時應該釋放它以及由誰釋放。

2

出於同樣的原因,您不能通過傳遞值來初始化整數。

1

兩點在這裏提出:

1)

int* b; 

這確實應該:

int* b = NULL; 

這只是因爲它是因爲你下運行的空調試報告調試。編譯下發佈會給b一個隨機指針。

2)

如果你傳遞一個指針的指針,那麼你的功能應該能夠分配內存:

int* b = NULL; 
Something::foo(&b); 

void Something::foo(int** a) 
{ 
    *a = new int[4]; 
} 
0

你必須使用一個參考或做類似:

int* b; 
foo(b); 

void Something::foo(int** a) 
{ 
    *a = new int[4]; 
} 

(這是老派的C做法,我認爲參考比較好)

0

因爲您將NULL傳遞給該函數。你需要的是像(指針的指針):

int* b; 
foo(b); 

void Something::foo(int** a) 
{ 
    *a = new int[4]; 
} 
1

指針是一個整數值(32位操作系統是32位整數),這是內存地址。您將整數值傳遞給函數。通過通過將值推入堆棧。然後,您從堆棧中刪除該值,並通過爲其分配一些內存來更改該值。然後退出該功能並刪除堆棧幀。該堆棧幀中的任何值都將被刪除,包括您新分配的內存地址。

你想要做的是傳遞一個指針指針。

int* b; 
foo(&b); 

void Something::foo(int** a) 
{ 
    *a = new int[4]; 
} 

在這裏,您聲明灣它是一個指向內存位置的整數值。你傳入該整數值的地址。即ANOTHER指向內存位置的整數值,該位置包含指向內存位置的整數值。現在在foo函數 中,您將內存分配給您指向的指向另一個內存位置的地址。然後當你退出函數時,堆棧展開並且指針指針消失。但是,您的原始整數值(即指針)仍然保留您剛創建的值,而您的調用是新的。

+0

+1用於良好的低級解釋。 – 2009-08-11 14:06:45