我正在学习结构和链接列表。但是我遇到了一个问题,导致我无法调试程序的错误,因为它似乎来自函数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
出了什么问题?
答案 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);