2014-03-06 22 views
1

我不知道如果我創建我的本地變量的方式是未定義的行爲。我是否以定義的方式使用局部變量?

N和L都保存一個指向臨時堆棧地址的指針。這安全嗎?編譯器會忘記我正在使用一個指向堆棧地址的指針,並用別的東西(比如其他局部變量)覆蓋它?我知道一旦函數的作用域結束它是不安全的。但我不確定下面的例子。任何洞察力將不勝感激。感謝您的時間。

struct Node { /* ... */ }; 

struct Node* 
Node_setNode(struct Node* node) 
{ 
    /* ... */ 
    return node; 
} 

struct List { /* ... */ }; 

void 
List_push(struct List* list, struct Node* node) 
{ 
    /* ... */ 
    list->next = node; 
} 


int main() 
{ 

    struct Node* N = Node_setNode((& ((struct Node){ 0 }))); 
    struct List L; 
    List_push(&L, (& ((struct Node){ 0 }))); 

    return 0; 
} 
+0

我很確定把一個指向'(struct Node){0}'的指針這樣不安全。儘管如此,我不確定它爲什麼編譯,所以也許我錯過了一些東西。 – user2357112

+0

@ user2357112'(struct Node){0}'的效果就像聲明'struct Node tmp = {0};'一樣,但沒有命名局部變量。它會在堆棧上創建一個空間。我覺得很難閱讀,所以我不會推薦它,但它的工作原理。 – Luke

回答

3

堆棧的關鍵在於你可以將事物推到最上面。

當你調用另一個函數時,你用一個局部變量推新的棧幀,而不影響main()的較低棧幀。

函數中聲明的變量將保留在其堆棧中,直到它返回。

+0

是的,我明白這一點。我試圖理解,如果使用指針堆棧地址以我顯示的方式不會被同一堆棧框架中的其他局部變量覆蓋。 –

+0

@ joe.ds:編譯器不會覆蓋仍在範圍內的變量的地址。 – SLaks

2

不,編譯器不會忘記你的局部變量。你使用它們的方式是安全和良好的。

只要確保你永遠不會返回一個指向棧上的東西的指針,你應該沒問題。

相關問題