簡體   English   中英

在C語言中,我可以通過堆棧指針訪問另一個函數中main函數的局部變量嗎?

[英]In C language, can I access local variable of main function in another function through stack pointer?

我需要訪問在 main 函數中定義的變量 a 的值,而不將其作為參數傳遞。

main()
{
    int a=10;

    func();

    printf("%d\n",a);
}

void func(){
//i need access of variable a here.
}

我該怎么做?

您可以將指向a指針傳遞給您的函數。 只要相應的局部變量存在,指向局部變量的指針就是有效的。 所以

#include <stdio.h>

void func(int *ptr);

main()
{
    int a = 10;

    // Pass pointer to a
    func(&a);

    printf("%d\n", a); // Prints 12
}

// function accepts pointer to variable of type int
void func(int *ptr)
{
    // update value behind the pointer
    *ptr = 12;
}

您不能這樣做,因為該變量甚至可能不存在,然后func()被調用。 在您的示例中,編譯器很可能會優化它並有效地創建此代碼:

main()
{
    func();

    printf("%d\n",10);
}

如果您確定變量沒有被優化掉,它很可能被存儲在某個寄存器中。 那個寄存器,如果你知道它是哪個,也許可以從func()訪問,或者它可以存儲在堆棧中。 但如果你是確保a實際上是在通過StackFrame分配main()你可以在堆棧中向下搜索挖掘指針main()和訪問的StackFrame main() 但是您仍然不知道a在堆棧幀中的位置。

如果這是一個純粹的理論問題(如評論所說)的答案可能是一個存儲指向a全局變量。 (盡管我無法想出該解決方案具有任何實際好處的任何現實世界場景)。

static int *ptr;

main()
{
    int a=10;
    ptr=&a;

    func();

    printf("%d\n",a);
}

void func(){
    // update value behind the pointer
    *ptr=12;
}

局部變量存儲在堆棧中,並且在堆棧中有一個地址。 我們可以做的是通過改變堆棧指針地址開始檢查堆棧指針地址,直到獲得與局部變量相同的地址,然后您可以對其進行所需的操作。 當然,這不是 c 編程的正確方法,但這是唯一的方法。 下面是代碼。

注意:TriedAndTested 的值取為 13,因為我在將堆棧指針遞增 13 次后得到了地址。 它可能在其他編譯器中有所不同。 相反,可以比較地址,然后對其進行評估。

#include<stdio.h>
#define TriedAndTested 13 //keep incrementing until you get the value of a
void func(){
    void *p=NULL;
    int *st;
    int i=0;
    st=(void *)&p;
    printf("p is %ld\n",st);
    for(i=0;i<TriedAndTested;i++){
        st++;
        printf("p is %ld\n",*st);}
    printf("p is %ld\n",++(*st)); //here i am incrementing the value of a
}

int main(){
    int a = 89; //trying to change the value of a in func()
    func();
    printf("%ld -> %d\n",&a,a);
    return 0;
}

不,因為每個局部變量都被推入相應函數的堆棧幀中,並且每個函數只能使用當前幀指針訪問自己的堆棧幀。

注意:這對 ARM GCC 9.2.1 有效

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM