2017-06-13 25 views
1

我正在學習結構和鏈表。不過,我面臨的一個問題是,我無法調試我的程序的錯誤,因爲它來自於函數printf,這是我用來調試程序的。它看起來像一個printf使我的程序bug

下面的程序工作正常:

struct pointer_struct 
{ 
    struct new_struct *ptr; 
}; 

struct new_struct 
{ 
    int i; 
    struct new_struct *ptr; 
}; 

void init(struct pointer_struct *pointer, int nb) 
{ 
    struct new_struct my_struct; 
    my_struct.i = nb; 
    my_struct.ptr = NULL; 
    pointer->ptr = &my_struct; 
} 

int main(void) 
{ 
    struct pointer_struct pointer; 
    pointer.ptr = NULL; 

    init(&pointer, 15); 
    //printf("pointer.ptr = %p\n", pointer.ptr); 
    printf("pointer.ptr->i = %d\n", pointer.ptr->i); 
} 

輸出:

pointer.ptr->i = 15 

但只要我去掉了註釋行,i需要怪異值。以下是一些輸出示例:

$./a.out 
pointer.ptr = 0x7fffc6bcc650 
pointer.ptr->i = -448723664 
$./a.out 
pointer.ptr = 0x7fffd09ed480 
pointer.ptr->i = 1218512176 
$./a.out 
pointer.ptr = 0x7ffff630fa70 
pointer.ptr->i = -1073674960 

printf怎麼回事?

+5

'的init(結構pointer_struct *指針,INT NB)'使用本地變量'結構new_struct my_struct;'在'指針 - >的ptr =&my_struct;'其中在函數結束後是_pointless_(壞雙關語)。 – chux

+0

你的意思是指針'pointer.ptr',它被賦予了這個局部變量的地址的值,指向一個地址,其中*有一個變量,由於printf,這個變量可能不在這裏了嗎? – nounoursnoir

+2

*指向有變量的地址*是。 *這可能不在這裏*確切地說。 *因爲printf *不,不是因爲printf。因爲變量曾經返回的函數。 –

回答

3

你用一個局部變量初始化pointer.ptr。

void init(struct pointer_struct *pointer, int nb) 
{ 
    struct new_struct my_struct; 
    my_struct.i = nb; 
    my_struct.ptr = NULL; 
    pointer->ptr = &my_struct; // MISTAKE!!! my_struct is on the stack. 
           // its memory space could be overwritten at 
           // any time after the function returns. 
} 

後來,在主

printf("pointer.ptr = %p\n", pointer.ptr); // This call to printf uses the stack, 
              // and overwrites the space used 
              // by my_struct 
    printf("pointer.ptr->i = %d\n", pointer.ptr->i); 
4

你有一個未定義的行爲或UB,它總是一個壞事™。

void init(struct pointer_struct *pointer, int nb) 
{ 
    struct new_struct my_struct; 
    my_struct.i = nb; 
    my_struct.ptr = NULL; 
    pointer->ptr = &my_struct; 
} // here my_struct lifetime is finish so pointer->ptr become invalid 

int main(void) 
{ 
    struct pointer_struct pointer; 
    pointer.ptr = NULL; 

    init(&pointer, 15); 
    printf("pointer.ptr = %p\n", pointer.ptr); // pointer.ptr is not valid so it's UB 
    printf("pointer.ptr->i = %d\n", pointer.ptr->i); // This is UB too 
} 
+0

你說「pointer.ptr無效,所以它是UB」。 pointer.ptr被分配了一個地址。即使使用這個地址的函數完成了,不應該指針總是指向地址,即使它可能有任何內容嗎? – nounoursnoir

+0

函數'init'不會爲'struct pointer_struct * pointer'指定任何值 –

+0

@nounoursnoir「即使使用此地址的函數完成了,不應該指針始終指向地址,即使可能有任何內容它?「,不。 – Stargateur

相關問題