2017-04-01 31 views
-2

我有一個相對簡單的問題,我試圖保持儘可能最小的問題,但希望包含一個例子,以便人們能夠理解我所引用的內容。局部變量指向投射

我有一個函數聲明一個局部變量(unsigned int),然後我使用一個指針將該unsigned int的值複製到一個指針。我知道在該函數結束之後,該局部變量將不再存在。唯一真正重要的是價值。然後我試着將它傳遞給func2()它必須有一個void *作爲參數(是不是我的選擇),只是單純的看價值,我認爲應該是2自從我加入1

void func2(void * arg){ 
    //was not my choice to have void * be the argument.. was a requirment 

    unsigned int val = *(unsigned int) arg; 
    //When I print this the value should be 2.. 


} 

void createPointer(){ 
    unsigned int localVariable = 1; 
    localVariable = localVariable + 1; 
    unsigned int *pointer = &localValue; 
    *pointer = localValue; 
    //my goal here is to copy the VALUE of the local variable 
    //as I need this pointer to still point to this value after this function returns 

    //in my actual code, this function is on a whole seperate file.. so it is really important that the pointer is stored in memory 

func2((void *) pointer); 


} 

int main(int argc, char *argv[]){ 
    createPointer(); 
} 

但是,當我試圖在func2()中打印變量val時,它只是打印出一些隨機地址作爲文本,這讓我認爲它仍然引用了localVariable,我只想複製它的值。

所以,我的問題是有沒有適當的語法方法來複制本地變量的值?當我投射並取消投射到void *時,我做錯了什麼?

+0

此代碼不會編譯... –

+1

請顯示真正完整的代碼。那是[mcve]。代碼存在多個問題,並且我們不知道這是否代表您的代碼的真實性,或者它是否只是您描述問題的方式中的問題。因此,總是顯示一個完全重現你的問題的MCVE。 – kaylum

+0

@OliverCharlesworth是 – Gaurav

回答

0

這個問題似乎在這裏

unsigned int val = *(unsigned int) arg; 

這是病態形成,如果編譯在所有我會感到非常驚訝,但既然你說的問題是打印的值是奇怪,我會假設,它的原因是,正確的方法是

unsigned int val = *(unsigned int *) arg; 

這意味着,鑄argunsigned int指針和解除引用它。

有幾件事情需要再提一下您傳遞指針,這

  1. 無論原值不再有效後,主叫返回是無關緊要的,因爲如果你把這個順序func2()應該在調用者之前返回並因此在之後發生釋放,所以該值將在func2()的生存期內有效。

  2. 現在存儲在val中的函數內部的值存在於func2()的堆棧幀中,並且是原始值的副本,但原則上位於不同的存儲器位置。

  3. 如果該功能將在不同的線程中執行,你不能假設您複製了啓動新線程的函數返回前的值,所以你需要的值存儲在堆,這樣

    int *pointer; 
    pointer = malloc(sizeof pointer); 
    if (pointer == NULL) { 
        handle_allocation_error(); 
    } else { 
        *pointer = value; 
        func2(pointer); 
        pointer = NULL; // Prevent having a dangling 
            // pointer 
    } 
    

,並在某些時候在func2()你需要free()指針。

原則上,這會工作,因爲你的示例代碼不像你的真實代碼。下一次,請包括實際代碼,如果實際代碼太多,請編寫能夠重現問題的較小版本。有時候,當你正在寫這麼小的版本時,你會發現爲什麼意外的行爲正在發生,你根本不需要問。

而且,你不需要(void *)

func2((void *) pointer); 

只是

func2(pointer); 

應該編譯罰款。

+0

你不需要從'void *'中隱式投射。 – user7771338

+0

@͘͘͘͘͘͘͘͘͘͘͘͘͘͘͘͘͘͘͘͘我無法真正理解您的評論。 –