我知道這有一個非常簡單的解釋,但我被寵壞了一段時間不必使用指針。爲什麼我不能通過將指針傳遞給函數來初始化數組?
爲什麼我不能做這樣的事情在C++
int* b;
foo(b);
和初始化通過陣列...
void Something::foo(int* a)
{
a = new int[4];
}
調用foo(B),B仍然是空之後。爲什麼是這樣?
我知道這有一個非常簡單的解釋,但我被寵壞了一段時間不必使用指針。爲什麼我不能通過將指針傳遞給函數來初始化數組?
爲什麼我不能做這樣的事情在C++
int* b;
foo(b);
和初始化通過陣列...
void Something::foo(int* a)
{
a = new int[4];
}
調用foo(B),B仍然是空之後。爲什麼是這樣?
通過值將指針傳遞給函數。實質上,這意味着指針值(但不是指針!)被複制。你修改的只是原始指針的副本。
有兩個解決方案,無論是使用間接的附加層:
要麼使用的引用:
void f(int*& a) {
a = new int[4];
}
或者你在一個指針到指針傳遞(以下傳統的輸出參數如您的情況):
void f(int** pa) {
*pa = new int[4];
}
並調用函數li柯本:
f(&a);
就個人而言,我不喜歡這兩種風格:參數是功能輸入,輸出應該是返回值進行處理。到目前爲止,我還沒有看到在C++中偏離這個規則的令人信服的理由。所以,我的建議是:改用下面的代碼。
int* create_array() {
return new int[4];
}
您可以通過值將參數傳遞給foo。更改爲
foo(int*& a)
您正在傳遞價值。
您需要通過按引用:
void Something::foo(int* &a)
{
a = new int[4];
}
也許是更清楚這樣做:
int* Something::foo()
{
int* a = new int[4];
return a;
}
int* b = foo();
確保當你返回一個指針(或更新參考)由一種方法分配的內存,它清楚何時應該釋放它以及由誰釋放。
出於同樣的原因,您不能通過傳遞值來初始化整數。
兩點在這裏提出:
1)
int* b;
這確實應該:
int* b = NULL;
這只是因爲它是因爲你下運行的空調試報告調試。編譯下發佈會給b一個隨機指針。
2)
如果你傳遞一個指針的指針,那麼你的功能應該能夠分配內存:
int* b = NULL;
Something::foo(&b);
void Something::foo(int** a)
{
*a = new int[4];
}
你必須使用一個參考或做類似:
int* b;
foo(b);
void Something::foo(int** a)
{
*a = new int[4];
}
(這是老派的C做法,我認爲參考比較好)
因爲您將NULL傳遞給該函數。你需要的是像(指針的指針):
int* b;
foo(b);
void Something::foo(int** a)
{
*a = new int[4];
}
指針是一個整數值(32位操作系統是32位整數),這是內存地址。您將整數值傳遞給函數。通過通過將值推入堆棧。然後,您從堆棧中刪除該值,並通過爲其分配一些內存來更改該值。然後退出該功能並刪除堆棧幀。該堆棧幀中的任何值都將被刪除,包括您新分配的內存地址。
你想要做的是傳遞一個指針指針。
int* b;
foo(&b);
和
void Something::foo(int** a)
{
*a = new int[4];
}
在這裏,您聲明灣它是一個指向內存位置的整數值。你傳入該整數值的地址。即ANOTHER指向內存位置的整數值,該位置包含指向內存位置的整數值。現在在foo函數 中,您將內存分配給您指向的指向另一個內存位置的地址。然後當你退出函數時,堆棧展開並且指針指針消失。但是,您的原始整數值(即指針)仍然保留您剛創建的值,而您的調用是新的。
+1用於良好的低級解釋。 – 2009-08-11 14:06:45
爲什麼你會在C++(也許在C)中寫'f(int ** pa)'。現在你需要檢查NULL。你可以重新安排,以便更安全的技術在頂部(並添加NULL檢查)。 – 2009-08-11 16:15:13
@Martin:'NULL'檢查根本沒有幫助,因爲你在C++中真正需要的是一個指針合法性檢查 - 它不存在。所以不行,代碼是完整的,雖然很脆弱,但是調用者的責任是確保指針是正確的,我同意這不是你想寫的代碼。 *但是,實際上有些人會看到這種風格的好處,因爲它在調用者的網站上顯而易見*該函數修改了參數的值。這在參考文獻中並不明顯。就我個人而言,我不同意 - 但是,我永遠不會使用'out'參數。 – 2009-08-11 17:40:52