如何解决指针丢失参考的问题
我正在尝试为孩子和父亲做一棵树,但是当孩子出生于一种功能中时,我却不再提及他们,这里将以狗为例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
typedef struct Dog{
int id;
double amound_of_bones;
int *bones;
int *gifts;
struct Dog *other_dog;
}Dog;
void have_children(Dog *father){
Dog pancho;
pancho.id=5;
pancho.amound_of_bones=1544.5;
(*father).other_dog=&pancho;
}
int main(int argc,char *argv[]) {
Dog pepi;
have_children(&pepi);
printf("the dog id: %d,have %f bones\n",(*pepi.other_dog).id,(*pepi.other_dog).amound_of_bones);
printf("the dog id: %d,(*pepi.other_dog).amound_of_bones);
return 1;
}
这是奇怪的输出:
the dog id: 5,have 1544.500000 bones
the dog id: 0,have 0.000000 bones
您将看到第一个输出运行良好,而另一个输出丢失了参考,我不知道如何解决
解决方法
Dog pancho;
是have_children()
函数中的局部变量。当函数返回时,该内存被释放。您将指针保存到不再有效的内存中。此行为是不确定的。
在函数have_children
中,变量pancho
是局部变量。这意味着变量的生存期仅与函数have_children
一样长。当该函数返回时,变量pancho
将不复存在,并且将不再为该对象保留内存。这意味着该内存可以被程序的其他部分使用,这将导致该内存被覆盖。
因为您将pancho
的地址分配给pepi->other_dog
,所以在pancho
的生存期结束后,即在函数have_children
之后,该指针将指向无效的对象返回。这意味着pepi->other_dog
将成为dangling pointer。
取消引用此类悬空指针会导致undefined behavior。
第一个printf
调用起作用的原因可能是因为对象的内存尚未被覆盖。第二个printf
调用会给您不同的结果,可能是因为第一个printf
调用在内部将内存地址用于其他用途,所以它被其他一些值覆盖。
要解决此未定义的行为,必须确保所指向的对象的生存期不会过早过期。例如,您可以改用功能malloc
。这样,对象的生存期将持续到您调用free
为止。
以下是如何重写函数have_children
以使用malloc
的示例:
#include <assert.h> //this header is required for the "assert" macro used below
void have_children(Dog *father){
Dog *pancho = malloc( sizeof(Dog) );
assert( pancho != NULL );
pancho->id = 5;
pancho->amound_of_bones = 1544.5;
father->other_dog = pancho;
}
不需要assert
宏,但是通常习惯检查malloc
的返回值以确保它不是NULL。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。