看起来像printf会导致我的程序错误

时间:2017-06-13 21:50:40

标签: c

我正在学习结构和链接列表。但是我遇到了一个问题,导致我无法调试程序的错误,因为它似乎来自函数printf,这是我用来调试程序的。

以下程序运行正常:

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出了什么问题?

2 个答案:

答案 0 :(得分: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
}

答案 1 :(得分: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);