【问题标题】:Pointer changes for apparently no reason - C指针显然无缘无故更改 - C
【发布时间】:2018-04-09 14:21:20
【问题描述】:

我有一个学校作业,要用 C 创建一个各种各样的数据库,我可以在其中从文件或键盘读取,但数据库本身存储在内存中。

现在,我不会直接就作业寻求帮助,但由于我是 C 新手,我不明白为什么我编写的这段代码不起作用。

源文件的一部分,应该将一个学生添加到链表中。

想在此处添加这些,我将初始值设置为 NULL。


struct student *student_root = NULL;
struct teacher *teacher_root = NULL;

    void add_student(char *name) {
    if (student_root == NULL) { //if there is no student in the list

        /* Allocate memory equivalent to the size of struct student
        and store the address in student_root */
        student_root = malloc(sizeof(struct student));
        // ^ this is something I tried to do to fix it, but I think it is not needed

        struct student new; //creating the student root
        inn_student(&new); //innitializing the root
        student_root = &new;
        set_sn(student_root, 1);//sn = student number, like an ID
        set_student_name(student_root, name);

        student_out(*student_root);this works here
    }
    else {
        struct student new; //creating the student that is to be added
        inn_student(&new); //innitializing the student that is to be added

        set_student_name(&new, name);

        printf("%d\n", student_root->student_number);//when I do this, I get a random number instead of '1'
        set_next_student(student_root, &new); // adding the new student to the list (student number is added automatically)
    }
}

我面临的问题是我第一次插入时,student_root 指针正在工作,它指向“新”学生结构。 . .但是当我添加其他东西时,它不起作用。函数完成后,“新”结构是否会被遗忘在内存中?如果是这样,如何解决?

【问题讨论】:

  • struct student new; : newadd_student 函数中的局部变量。它在函数范围之外变得无效。
  • 该语句不会像您想象的那样将“本地​​”学生实例复制到先前分配的内存中:student_root = &new; 所以 `student_root` 在您离开后指向不属于您的内存函数。
  • 如果要开始存储指向它的指针,了解对象的生命周期是非常重要的!
  • 此外,“创建新学生/初始化/分配号码”代码在两种情况下都重复。在if 之外执行此操作,并让if 仅确定如何将新学生添加到列表中。
  • 尽量避免使用new作为变量名

标签: c list function pointers


【解决方案1】:
student_root = malloc(sizeof(struct student));

struct student new; //creating the student root
inn_student(&new); //innitializing the root
student_root = &new;

在您初始化student_root 以指向一个堆位置后,接下来几行您再次将其设置为指向一个自动局部变量,当您从该函数返回时,该变量的内存将被其他代码重写。

正确的做法是初始化inn_student(student_root)的字段,而不是inn_student(&new)

【讨论】:

  • 我编辑了我的帖子。为 student_root 分配堆空间后,无需使用自动变量 new
  • 不行,你必须把栈上的局部变量new的内容memcopy放到你之前在student_root中分配的堆内存中,而不是仅仅分配指针。
  • 是的,成功了!对于那些有类似问题的人,这是固定代码。 /* Allocate memory equivalent to the size of struct student and store the address in student_root */ student_root = malloc(sizeof(struct student)); struct student new; //creating the student root inn_student(&new); //innitializing the root *student_root = new; //instead of setting the pointer to the struct that will be automatically deleted, the student_root gets a copy of the data ------ 我试图让它看起来不错,但我做不到:c
  • 或者,通过将第三条语句从 student_root = &new 更改为 *student_root = new,代码将按预期工作。这会更改动态分配的对象,并且当new 超出范围时,它不再存在。
  • @StefanHorvath 正如@Peter 所说,*student_root = new 也是正确的,memcpy 也复制了填充位,这没有用。
猜你喜欢
  • 1970-01-01
  • 2019-06-24
  • 1970-01-01
  • 2012-04-16
  • 1970-01-01
  • 1970-01-01
  • 2010-12-24
  • 2011-08-05
  • 1970-01-01
相关资源
最近更新 更多