2011-03-25 70 views
0

我對函數調用之間的指針發生了什麼感到困惑。這不是我所期望的。我有以下情況:指針在整個函數調用中保持信息

SomeClass *p1= 0, *p2 = 0; 
SomeMethod(p1, p2); 
printf("P1 total: %d\n", p1->total); // crashes 
printf("P2 total: %d\n", p2->total); // crashes 

// method someMethod, where the values of the pointers are valid 
void SomeMethod(SomeClass *p1, SomeClass *p2) 
{ 
    someMethodThatModifiesThePointers(&p1, &p2); 
    printf("P1 total: %d\n", p1->total); // prints valid value 
    printf("P2 total: %d\n", p2->total); // prints valid value 
}; 

你可以從我的意見看,指針的。總屬性(整數)是該方法的內有效,但不再是它的外部有效。爲什麼會這樣?指針不應該丟失範圍。

準確地說,someMethodThatModifiesThePointers()是opencv的cvExtractSURF。我拉開了代碼以保持簡單。

回答

3

C是一種傳值語言。這意味着您的原始功能中的指針不能通過調用SomeMethod()(其中C沒有方法)來更改。你在註釋行上崩潰,因爲當時p1p2仍然是空指針。

SomeMethod()內部的指針也是如此。如果您將空指針傳遞給SomeMethod(),那麼由於相同的原因,您的線路編號prints valid value將會崩潰。你不可能得到你所說的輸出結果,至少給出了你所顯示的代碼。如果你在你的例子犯了一個錯誤,並且你的意思是這條線是:

someMethodThatModifiesThePointers(&p1, &p2); 

它可以工作,你解釋的方式 - p1p2然後通過引用傳遞(也就是要傳遞一個指針指針指針),它們的值可以在SomeMethod()內有效。然而,在代碼頂部的p1p2的原始副本仍然會有空指針。

你可以做同樣的解決您的問題 - 通過引用傳遞p1p2SomeMethod()

SomeMethod(&p1, &p2); 

這種變化將要求您做出SomeMethod()一些修改:

void SomeMethod(SomeClass **p1, SomeClass **p2) 
{ 
    someMethodThatModifiesThePointers(p1, p2); 
    printf("P1 total: %d\n", (*p1)->total); 
    printf("P2 total: %d\n", (*p2)->total); 
}; 

後您的頂級功能中的此調用p1p2將按照您希望的方式運行。

+0

請注意,您可以/必須通過另一個指針(即'SomeClass **'參數,將'&p1'傳遞給'SomeMethod'等等)模擬傳遞引用。 – delnan 2011-03-25 18:11:09

+0

對不起,我在我的原始代碼中犯了一個小錯字,但我認爲它不會改變任何內容。只需在函數調用中的參數前添加&。 someMethodThatModifiesThePointers是cvExtractSURF,它實際分配和填充指針(它從圖像中收集SURF點並用SURF點填充指針)。 – vapo 2011-03-25 18:11:29

+0

@vapo,這就是我的想法。在我的答案中同樣的解釋仍然適用。 – 2011-03-25 18:12:21

0

發生了什麼事是......

:創建一個指向SomeClass的一個「實例」。

GCC:沒問題!完成。

:分配0x0作爲該指針的值。也就是說,它指向的'對象'位於內存中的位置0x0

GCC:好的,0x0不屬於你的程序,但我會隨它一起滾動。

:好的。接下來,用我的全新SomeClass實例做點什麼!編譯並運行!

操作系統:WOAH WOAH等一下,破壞者。你應該考慮使用malloc()先問我一些內存。 0x0的內存位置屬於我,而不是你。一般保護錯誤,快樂,享受崩潰。 (順便說一下,術語'class','instance'等是面向對象的編程術語,它們不完全屬於C.我們通常在這裏討論結構,函數和指針:)

+0

大聲笑我希望海灣合作委員會和操作系統會這樣跟我說話。 – GWW 2011-03-25 18:10:15

+0

我的道歉和感謝的解釋。我在上面的代碼中發現了一個輕微的錯字。主要參數傳遞給someMethodThatModifiesThePointers – vapo 2011-03-25 18:12:12

0

指針的.total屬性(整數)在方法內有效,但不再有效。爲什麼會這樣?

鑑於它打印內部SomeMethod打印有效值有效值和對SomeMethod的回報崩潰了這樣的事實,我想這兩個p1,p2按值傳遞。在返回SomeMethod後,兩個p1,p2都是空指針並取消引用它來解釋崩潰。您需要發佈someMethodThatModifiesThePointers(p1, p2);的代碼。

0

混淆的部分原因是您已爲函數外部和內部的指針選擇了相同的名稱。試試這個:

SomeClass *p1= 0, *p2 = 0; 
SomeMethod(p1, p2); 
printf("P1 total: %d\n", p1->total); // crashes 
printf("P2 total: %d\n", p2->total); // crashes 

// method someMethod, where the values of the pointers are valid 
void SomeMethod(SomeClass *p3, SomeClass *p4) 
{ 
    someMethodThatModifiesThePointers(&p3, &p4); 
    printf("P3 total: %d\n", p3->total); // prints valid value 
    printf("P4 total: %d\n", p4->total); // prints valid value 
}; 

指針p1和p2分別複製到P3和P4,而不是倒過來。