这段C代码在运行时声明了一个错误(segfault)

r6l8ljro  于 2023-05-06  发布在  其他
关注(0)|答案(2)|浏览(98)
#include <stdio.h>
#include <stdlib.h>

struct chambre {
  int num;
  struct chambre *prd;
  struct chambre *svt;
};
typedef struct chambre chambre;

struct ascenseur {
  char c;
  struct chambre *etage;
  struct ascenseur *etage_svt;
  struct ascenseur *etage_prd;
};
typedef struct ascenseur ascenseur;

ascenseur *rdch = NULL;

ascenseur *Ajout_Etage(int up) {
  ascenseur *new_Etage = NULL;
  ascenseur *etage_up = rdch;
  for (int i = 0; i < up; i++) {
    etage_up = etage_up->etage_svt;
  }

  new_Etage = malloc(sizeof(ascenseur));
  (etage_up->etage_svt)->etage_prd = new_Etage;
  new_Etage->etage_svt = (etage_up->etage_svt);
  new_Etage->etage_prd = etage_up;
  etage_up->etage_svt = new_Etage;

  new_Etage->c = 'X';

  new_Etage->etage = malloc(sizeof(chambre));
  chambre *p = new_Etage->etage;
  p->num = 1;
  p->svt = p;
  p->prd = p;

  chambre *nouv;
  chambre *pre = p;
  for (int i = 2; i < 6; i++) {
    nouv = malloc(sizeof(chambre));
    p->prd = nouv;
    nouv->num = i;
    nouv->prd = pre;
    pre->svt = nouv;
    pre = nouv;
  }
  return new_Etage;
}

int main() {
  int i;
  // ascenseur * rdch=NULL;
  ascenseur *new_rdch, *rdch_prd;

  rdch = malloc(sizeof(ascenseur));
  rdch->c = 'A';
  rdch->etage_prd = NULL;
  rdch->etage_svt = NULL;

  rdch->etage = malloc(sizeof(chambre));
  chambre *p = rdch->etage;
  p->num = 1;
  p->prd = p;
  p->svt = p;

  //=============

  chambre *nouv;
  chambre *pre = p;
  for (i = 2; i < 6; i++) {
    nouv = malloc(sizeof(chambre));
    p->prd = nouv;
    nouv->num = i;
    nouv->prd = pre;
    pre->svt = nouv;

    pre = nouv;
  }

  printf("%c -> : ", rdch->c);
  printf("%d", p->num);
  printf(" %d ", (p->svt)->num);

  printf("\n_______________________ : \n");

  //==================================================
  rdch_prd = rdch;
  for (int j = 1; j < 6; j++) {
    new_rdch = malloc(sizeof(ascenseur));

    new_rdch->c = 'A' + j;
    new_rdch->etage_prd = rdch_prd;
    new_rdch->etage_svt = NULL;

    rdch_prd = new_rdch;

    new_rdch->etage = malloc(sizeof(chambre));

    p = new_rdch->etage;
    p->num = 1;
    p->prd = p;
    p->svt = p;

    //=============

    pre = p;
    for (i = 2; i < 6; i++) {
      nouv = malloc(sizeof(chambre));
      p->prd = nouv;
      nouv->num = i;
      nouv->prd = pre;
      pre->svt = nouv;

      pre = nouv;
    }

    printf("%c -> : ", new_rdch->c);
    printf("%d", p->num);
    printf(" %d ", (p->svt)->num);
    printf("\n_______________________ : \n\n");
  }
  ascenseur *etage_up = Ajout_Etage(3);
  printf("\n\n");

  printf("%c ==> : ", etage_up->c);
  // printf("%d ",(etage_up->etage)->num);

  return 0;
}

我将rdch指针声明为用“NULL”初始化的全局VAR。之后,通过main函数中的处理,rdch指针现在具有值(非NULL)。调试器声明etage_up=etage_up-\>etage_svt;行中的错误
我不知道函数“Ajout_Etage”是否将etage_up作为NULL,那么etage_up的etage_svt不存在......所以如果我是对的,为什么当main函数中的进程的rdch指针采用真实构建的真实的地址时,etage_up采用NULL值。

dw1jzc5e

dw1jzc5e1#

当你使用调试器的时候,你不仅应该试着找出崩溃发生的地方,还应该找出崩溃发生的时间。如果您逐个语句地进入代码,您应该注意到,是的,您在etage_up = etage_up->etage_svt上出错,但是在循环的第二次迭代上出错。这意味着问题与rdchetage_up指向的原始值)无关,而是与rdch->etage_svt(第一次迭代后etage_up指向的值)有关。
事实上,如果在调试器中检查rdch->etage_svt,您会注意到它是0,并且尝试取消引用它会导致崩溃。要解决这个bug,您需要将rdch->etage_svt分配给有效的对象。

cedebl8k

cedebl8k2#

1.您的程序segfaults in Ajout_Etage() as etage_up is NULL:

ascenseur *etage_up = rdch;
    for (int i = 0; i < up; i++) {
        etage_up = etage_up->etage_svt;
    }

up = 3,但全局变量rdch中只有1个节点。
1.如果你添加一个&& etage_up来修复上面的问题,那么它会因为同样的原因在(etage_up->etage_svt)->etage_prd = new_Etage;中segfault。
Ajout_Etage(3)假设你在etage_up->etage_svt链中有3个节点,但在main()中你只初始化了一个节点:

rdch = malloc(sizeof(ascenseur));
    rdch->c = 'A';
    rdch->etage_prd = NULL;
    rdch->etage_svt = NULL;

然后你做了:

rdch_prd = rdch;
    for (int j = 1; j < 6; j++) {
        new_rdch = malloc(sizeof(ascenseur));

        new_rdch->c = 'A' + j;
        new_rdch->etage_prd = rdch_prd;
        new_rdch->etage_svt = NULL;

        rdch_prd = new_rdch;
        // ...

这不会改变rdch
我建议你将代码分解成更小的函数,避免使用全局变量,并尽量减少变量的作用域。如果你想在Stack Overflow上获得最多的观众,你也想使用英语。

相关问题