2017-06-13 24 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

相关问题