簡體   English   中英

C 程序打印意外輸出

[英]C program printing unexpected output

我有以下 C 程序:

#include <stdio.h>

void setArr(int, int);

int *arr[10]; // array of 10 int pointers

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

    setArr(0, -10);
    setArr(1, 100);
    setArr(2, 200);
    setArr(3, 300);
    setArr(4, 400);

    for (i = 0; i < 5; i++)
        printf("arr[%d] -*-> %d %d\n", i, *arr[i], **(arr + i)); /* should be -10,100, 200,300,400 */
    return 0;
}

/* set arr[index], which is a pointer, to point to an integer of value v */
void setArr(int index, int v)
{
    int i = v;
    arr[index] = &i;
}

它提供以下輸出:

arr[0] -*-> 400 400
arr[1] -*-> 400 400
arr[2] -*-> 400 400
arr[3] -*-> 400 400
arr[4] -*-> 400 400

我的理解是arr中的每個元素都是一個指針,它將指向i在函數內創建的變量的位置。

我不確定它如何始終始終返回 400
此輸出的原因可能是什么以及如何糾正它?

定義int i = v; 在函數內部自動為i保留內存。 當函數的執行結束時,內存預留被釋放。

一旦內存預留被釋放,C 標准不保證任何指向內存的指針的值,您不應使用這些值。

每次調用setArr ,都會保留內存然后釋放。 一個常見的結果是使用相同的內存作為保留、釋放、保留、釋放等,並且指針似乎指向相同的位置。 然后您將arr每個元素都設置為指向相同的位置。 但是,編譯器的優化和其他操作可能會產生其他行為。

當然,該位置一次只能保存一個值,因此在調用setArr之后只能在其中看到一個值。

你的代碼毫無意義。

對於初學者來說,在 C 中,一旦包含它的函數退出,像i這樣的局部變量的地址將無效。

這意味着數組中的所有指針在setArr之外都無效。

其次,C 編譯器通常在堆棧上分配局部變量,這意味着每次調用setArr i可能都位於相同的地址,因此您看到的輸出是完全合乎邏輯的。

i的值每次調用都會被覆蓋,並且因為您在最后一次調用setArr后立即打印它,內存雖然在技術上是免費的,但尚未被覆蓋。

因此,幸運的是,您可以在所有printf調用中看到最后一次調用setArr的結果。

暫無
暫無

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

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