指针丢失引用的问题

problem with lost reference with pointers

我正在尝试做一棵 children 和父亲的树,但是当他们出生在一个函数中时,我失去了对孩子的引用,这里将以狗为例:

#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, have %f bones\n",(*pepi.other_dog).id,(*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() 函数中的局部变量。当函数 returns 时,该内存被释放。您保存了指向不再有效的内存的指针。此行为未定义。

在函数have_children中,变量pancho是局部变量。这意味着变量的生命周期仅与函数 have_children 一样长。当该函数 returns 时,变量 pancho 不复存在,内存将不再为该对象保留。这意味着内存可以被程序的其他部分使用,这将导致内存被覆盖。

因为您将 pancho 的地址分配给 pepi->other_dog,所以在 pancho 的生命周期结束后,即在函数 [=11] 之后,该指针将指向一个无效的对象=] return秒。这意味着 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 的 return 值以确保它不为 NULL 通常是一个好习惯。