2009-07-10 53 views
-1

作爲後,我想訪問變量V1 & V2在Func鍵(),而在main()訪問函數的變量調用它,而在main()

int main(void) 
{ 
    Func(); 
    int k = ? //How to access variable 'v1' which is in Func() 
    int j = ? //How to access variable 'v2' which is in Func() 
} 

void Func() 
{ 
    int v1 = 10; 
    int v2 = 20; 
} 

我聽說,我們可以從堆棧的存取權限。但是怎麼做。

謝謝。

回答

1

你在C/C++的土地。有一點你不能做。

如果這是您自己的代碼,您甚至不應該嘗試這樣做。像其他人一樣建議:通過引用(或通過C中的指針)傳遞一個輸出參數,或者返回一個結構體中的值。

不過,既然你問的問題,我假設你正試圖尋找到的東西,你只需要二進制訪問。如果只是一次性的話,使用調試器會更容易。

總之,要回答你原來的問題,請嘗試以下代碼。您必須爲x86 CPU編譯它,並關閉優化和任何堆棧調試標誌。

void f() { 
    int i = 12345; 
    int j = 54321; 
} 

int main() 
{ 
    int* pa = 0; 
    int buf[16] = {0}; 

    f(); 

    // get the stack pointer 
    __asm { 
     mov dword ptr [pa],ESP 
    } 

    // copy the stack, try not to do anything that "use" the stack 
    // before here  
    for (int i = 0; i < 16; ++i, --pa) { 
     buf[i] = *pa; 
    } 

    // print out the stack, assuming what you want to see 
    // are aligned at sizeof(int) 
    for (int i = 0; i < 16; ++i) { 
     std::cout << i << ":" << buf[i] << std::endl; 
    } 

    return 0; 
} 
+0

在C/C++的土地,有很多你不能這樣做,包括這個。你的意思是,「你在本地代碼的土地,並且你可以用實施細節搞砸,所以你沒有什麼不能做的」) – jalf 2009-07-10 15:31:06

9

你不能合法地做到這一點。自動變量消失,一旦執行離開他們聲明的範圍。

我確定有一些技巧,如檢查堆棧和及時「倒退」,但所有這些技巧是平臺相關的,並可能會中斷例如,如果您導致堆棧在main()中被覆蓋。

3

可以做到這一點的一些方法有:

  1. 聲明變量在main(),並通過指針或引用將它們傳遞到函數功能()
  2. 返回變量,或載體< int>的,或你創建的結構等變量main()
  3. 動態分配Func()中的變量,並返回一個指向它們的指針。之後您還必須記得在之後刪除分配的內存。

但是沒有從標準的main()中訪問Func()堆棧。

4

爲什麼你想這樣做?你想把這些值作爲返回值嗎?我要介紹的一個結構,根據值的結構會得到一個合適的名稱

struct DivideResult { 
    int div; 
    int rem; 
}; 

DivideResult Func() { 
    DivideResult r = { 10, 20 }; 
    return r; 
} 

int main() { 
    DivideResult r = Func(); 
} 

否則,這些變量是同時被激活的功能管理本地狀態的含義。在功能終止後,他們再也沒有任何意義或生活了。

2

你不能這麼做。當Func()的堆棧框架消失時,沒有可靠的方法來訪問它。它是免費的被踐踏。然而,在x86-64中,有一些被稱爲紅色區域的區域,它是堆棧指針下面的128B區域,可以安全地避免踐踏,理論上可能仍然能夠訪問它,但這不是可移植的,容易,也不正確。簡而言之,不要這樣做。

這是我會怎麼做:

int main(void) 
{ 
    int k, j; 
    Func(&k, &j); 
} 

void Func(int *a, int *b) 
{ 
    *a = 10; 
    *b = 20; 
}