C 好像是printf让我的程序出了问题
我正在学习结构和链表。然而,我面临着一个阻止我调试程序错误的问题,因为它似乎来自于我用来调试程序的函数C 好像是printf让我的程序出了问题,c,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
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有什么问题?您有一个未定义的行为或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
}
你有一个未定义的行为或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
}
您可以使用局部变量初始化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);
您可以使用局部变量初始化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);
init(struct pointer\u struct*pointer,int nb)
使用局部变量struct new\u struct my\u struct代码>在指针->ptr=&my_struct
在函数结束后是无意义的(糟糕的双关语)。您的意思是指针pointer.ptr
,它被赋予了这个局部变量的地址值,指向一个有一个变量的地址,这个变量可能不再存在,因为printf?指向一个有一个变量的地址Yes。可能已经不在这里了。因为printf不,不是因为printf。因为用于返回变量的函数。请使用所有警告和调试信息进行编译,例如使用gcc-Wall-Wextra-g
with。然后使用调试器gdb
和init(struct pointer\u struct*pointer,int nb)
使用局部变量struct new\u struct my\u struct代码>在指针->ptr=&my_struct
在函数结束后是无意义的(糟糕的双关语)。您的意思是指针pointer.ptr
,它被赋予了这个局部变量的地址值,指向一个有一个变量的地址,这个变量可能不再存在,因为printf?指向一个有一个变量的地址Yes。可能已经不在这里了。因为printf不,不是因为printf。因为用于返回变量的函数。请使用所有警告和调试信息进行编译,例如使用gcc-Wall-Wextra-g
with。然后使用调试器gdb
,您说“pointer.ptr无效,所以它是UB”。pointer.ptr被分配了一个地址。即使使用此地址的函数已完成,指针是否应始终指向该地址,即使其中可能有任何内容?函数init
不会为struct pointer\u struct*pointer
@nounoursnoir指定任何值“即使使用此地址的函数已完成,指针是否应该始终指向该地址,即使其中可能有任何内容?”,不。@WeatherVane wut?how?@Stargateur我将其称为危险行为,这是一个更好的名称。:)你说“pointer.ptr无效,因此它是UB。”“.pointer.ptr被分配了一个地址。即使使用此地址的函数已完成,指针是否应始终指向该地址,即使其中可能有任何内容?函数init
不会为struct pointer\u struct*pointer
@nounoursnoir指定任何值“即使使用此地址的函数已完成,指针是否应该始终指向该地址,即使其中可能有任何内容?”,否。@WeatherVane wut?如何?@Stargateur我称之为危险行为,这是一个更好的名称。:)