3

在动态内存分配方面,我是新手。当我们使用内存释放内存时void free(void *ptr),内存被释放但指针的内容没有被删除。这是为什么?最近的 C 编译器有什么不同吗?

4

5 回答 5

8

计算机不会像这样“删除”内存,它们只是停止使用对该内存单元的所有引用,并忘记那里存储了任何有价值的东西。例如:

int* func (void)
{
  int x = 5;
  return &x;
}

printf("%d", *func()); // undefined behavior

一旦函数完成,程序停止保留存储的内存位置,x程序的任何其他部分(或者可能是另一个程序)都可以自由使用它。所以上面的代码可以打印 5,或者打印垃圾,甚至可能使程序崩溃:引用不再有效的内存单元的内容是未定义的行为。

动态内存也不例外,并且以相同的方式工作。一旦你调用free()了 ,那部分内存的内容就可以被任何人使用。

另外,请参阅这个问题

于 2012-06-28T07:24:54.060 回答
3

问题是在内存被释放后访问内存是未定义的行为。不仅内存内容未定义,访问它们可能会导致任何事情。至少有些编译器在构建代码的调试版本时,实际上确实会更改内存的内容以帮助调试,但在发布版本中通常没有必要这样做,因此内存保持原样,但无论如何,这不是您可以安全依赖的东西,不要访问已释放的内存,这是不安全的!

于 2012-06-28T07:17:46.483 回答
1

在 C 中,参数是按值传递的。所以free不能改变ptr.
它所做的任何更改只会更改free函数中的值,并且不会影响调用者的变量。

此外,更改它不会有太大帮助。可以有多个指针指向同一块内存,释放时它们都应该被重置。该语言无法跟踪所有这些,因此它让程序员来处理指针。

于 2012-06-28T07:16:29.497 回答
1

这是很正常的,因为释放后清除内存位置是一种开销,通常没有必要。如果您有安全问题,可以将 free 调用包装在一个函数中,该函数在释放之前清除该区域。您还会注意到,这需要知道分配大小,这是另一个开销。

于 2012-06-28T07:18:22.927 回答
1

实际上,C 编程语言规定,在对象的生命周期之后,即使指向它的任何指针的值都变得不确定,即您甚至不能依赖指针来保留原始值。

这是因为一个好的编译器会尝试积极地将所有变量存储到 CPU 寄存器而不是内存中。所以它看到程序流程调用了一个以参数命名free的函数ptr后,它可以将free的寄存器标记ptr为其他用途,直到它被再次分配,例如ptr = malloc(42);

在这两者之间,可以看到更改值,或将其与其原始值进行比较,或其他类似行为。这是一个可能发生的例子

于 2017-11-20T04:30:58.973 回答