代码之家  ›  专栏  ›  技术社区  ›  Laz

垃圾收集者会在这里做什么?

  •  1
  • Laz  · 技术社区  · 14 年前

    我在另一个线程中看到了这段代码

    void foo {
      int *n = malloc(sizeof(int)); 
      *n = 10; 
      n++;
      printf("%d", *n);
    }
    

    这里的错误是显而易见的。 n 没有被取消引用。 内存泄漏。 n 现在是零因为 n 不再引用它了。所以它是垃圾然后又回来了。但是,你所指的新地点呢 n

    3 回复  |  直到 14 年前
        1
  •  1
  •   Roland Illig    14 年前

    正确实现的垃圾收集器的工作原理如下:

    int *pi = malloc(sizeof int);
    *pi = 10;
    

    这里一切都很好。

    pi++;
    

    这句话让我们 pi 在分配的int后面的点,这是isoc99标准明确允许的(参见6.5.6p7,6.5.6p8)。在代码的后面,可能有 pi-- ,因此仍然可以访问分配的int。也可以通过表达式访问 pi[-1]

    pi = NULL;
    

    此时,无法再访问分配的int,因此垃圾收集器可能会收集内存。

    总之:所有指向对象开头、对象中间某处或对象后面位置的指针都可以用来访问对象。因此,如果内存中存在这样的值,则不能对对象进行垃圾收集。

        2
  •  1
  •   John    14 年前

    C垃圾收集器不执行引用计数。它们通常是标记扫描,并且对块而不是单个字节进行操作。在您的示例中,gc将标记块,而不是地址。即便如此,你问题的核心仍然有效:

    作记号 当它到达一个“坏”指针时该怎么办?
    A 保守的

        3
  •  0
  •   Michael Mrozek    14 年前

    我改变了主意;我想是的。问题是这样的代码:

    int* n = malloc(sizeof(int));
    n++;
    int* o = n;
    int* p = n;
    n = malloc(sizeof(int));
    

    现在有三个引用指向 n n = NULL; 会导致清理 o p