2013-02-05 118 views
1

對不起,我不能支持我的問題與一些代碼(我不知道如何構造它,因此它會被接受在這裏),但我仍然嘗試。指向堆棧

如果我理解正確,那麼引用相同類型結構的結構將需要使用包含的指針進行引用。這個指針可以引用堆棧上的分配空間(而不是堆)而不會產生分段錯誤? -

這應該如何聲明?

+0

當你聲明時,你不需要做任何特殊的事情。指針是否指向堆棧,堆或NULL對包含它的結構的聲明沒有影響。 –

回答

0

是的,你可以使用堆棧指針上的變量,但只有當還沒有恢復提供該堆棧幀的方法。例如,這將工作:

typedef struct 
{ 
    int a; 
    float b; 
} s; 

void printStruct(const s *s) 
{ 
    printf("a=%d, b=%f\n", s->a, s->b); 
} 

void test() 
{ 
    s s; 
    s.a = 12; 
    s.b = 34.5f; 
    printStruct(&s); 
} 

這將導致錯誤然而,由於堆棧幀就會消失:

s *bad() 
{ 
    s s; 
    s.a = 12; 
    s.b = 34.5f; 
    return &s; 
} 

編輯:嗯,我說,這將導致一個錯誤,但在調用該代碼:

int main() 
{ 
    test(); 
    s *s = bad(); 
    printStruct(s); 
    return 0; 
} 

我在編譯過程中得到一個警告

s.c:27:5: warning: function returns address of local variable [enabled by default] 

和程序似乎很好地工作:

$ ./s 
a=12, b=34.500000 
a=12, b=34.500000 

但是,事實上,破碎。

+0

謝謝你的回答。我相信我明白爲什麼它應該被打破 - 但爲什麼它仍然有效? – stian

+0

這很可能是因爲堆棧沒有被重用*,因爲函數返回了,所以之前的所有東西仍然有效。如果其他函數(使用堆棧變量)被調用,那麼它肯定會失敗。 – trojanfoe

0

你沒有說什麼語言你的工作中,所以假設下,現在從你的問題的措辭...下面的代碼是完全合法:

typedef struct str_t_tag { 
    int foo; 
    int bar; 
    struct str_t_tag *pNext; 
} str_t; 

str_t str1; 
str_t str2; 
str1.pNext = &str2; 

在這個例子中都str1和str2在堆棧中,但如果其中一個或兩個堆在一起,這也可以工作。唯一需要注意的是堆棧變量在超出作用域時會被跳過,所以如果你已經動態分配了str1並將它從一個函數中傳回來,你不希望str1-> pNext指向在該函數中堆棧中的東西。

換句話說,不要做:

typedef struct str_t_tag { 
    int foo; 
    int bar; 
    struct str_t_tag *pNext; 
} str_t; 

str_t *func(void) 
{ 
    str_t *pStr1 = malloc(sizeof(*pStr1)); 
    str_t str2; 
    pStr1->pNext = &str2; 

    return pStr1; /* NO!! pStr1->pNext will point to invalid memory after this */ 
} 
+0

如果'pStr1'未初始化(如處理'malloc'行時的情況那樣)'sizeof(* pStr1)'會工作嗎? – Dukeling

+0

yes - sizeof在編譯時會被忽略,並且不需要初始化內容以知道它們的大小。 – Vicky

0

不知道這是否是特別的C/C++問題,但我會以C/C++代碼爲例。

的唯一方法可以聲明它:(有少許變化)

typedef struct abc 
{ 
    struct abc *other; 
} abc; 

other可以指向一個物體在棧上,如下所示:

abc a, b; // stack objects 
b.other = &a; 

這不是一個大約範圍問題,所以我會跳過評論上述做法的可能問題。

但是,如果要將其分配給動態創建的對象,則該對象無法位於堆棧上。

abc b; 
b.other = malloc(sizeof(abc)); // on the heap 
+0

偉大而詳細的答案:) – stian

+1

@dexter,如果這個或其他答案幫助你,那麼請upvote它(使用答案左側的向上箭頭)和/或接受它(使用綠色的勾號,也可以答案左側)。 – Vicky

+0

@vicky,obs,對不起。 – stian