在动态内存分配方面,我是新手。当我们使用void free(void *ptr)
释放内存时,内存被释放,但指针的内容不会被删除。这是为什么?最新的C编译器有什么不同吗?
答案 0 :(得分:8)
计算机不会“删除”内存,它们只是停止使用对该内存单元的所有引用,并忘记存储任何有价值的东西。例如:
int* func (void)
{
int x = 5;
return &x;
}
printf("%d", *func()); // undefined behavior
函数完成后,程序停止保留存储x
的内存位置,程序的任何其他部分(或可能是其他程序)都可以自由使用。所以上面的代码可以打印5,或者它可以打印垃圾,或者它甚至可能导致程序崩溃:引用已经停止有效的内存单元格的内容是未定义的行为。
动态内存也不例外,并以相同的方式工作。调用free()
后,任何人都可以使用该部分内存的内容。
另请参阅this question。
答案 1 :(得分:3)
问题是在释放后访问内存是未定义的行为。不仅内存内容未定义,访问它们也可能导致任何问题。至少有一些编译器在构建代码的调试版本时,实际上确实更改了内存的内容以帮助调试,但在发布版本中通常不需要这样做,因此内存只是保留原样,但无论如何,这不是你可以安全依赖的东西,不要访问释放的内存,这是不安全的!
答案 2 :(得分:1)
在C中,参数按值传递。因此free
无法更改ptr
的值
它所做的任何改变只会改变free
函数中的值,并且不会影响调用者的变量。
此外,更改它不会有太多帮助。可以有多个指针指向同一块内存,并且它们应该在释放时全部重置。语言无法跟踪它们,所以它让程序员处理指针。
答案 3 :(得分:1)
这是很正常的,因为在空闲后清除内存位置是一种开销,通常不是必需的。如果您有安全问题,可以将免费调用包装在一个函数中,该函数在释放之前清除该区域。您还会注意到这需要了解分配大小,这是另一种开销。
答案 4 :(得分:1)
实际上C编程语言指定在对象的生命周期之后,即使指向它的任何指针的值也变得不确定,即你甚至不能依赖指针指向偶数保留原始价值。
这是因为一个好的编译器会尝试将所有变量积极地存储到CPU寄存器而不是内存中。因此,在看到程序流使用参数free
调用名为ptr
的函数之后,它可以将ptr
的寄存器标记为其他用途,直到它再次被分配给它,例如ptr = malloc(42);
。
在这两者之间,可以看到改变价值,或将不等价与原始价值或其他类似行为进行比较。 Here's an example of what might happen