【发布时间】:2018-07-07 23:59:31
【问题描述】:
我知道分配给数组的内存会在数组超出范围时被释放,但是为什么在 C、C++ 和 Fortran 等语言中,动态数组在超出范围时不会自动被删除?
【问题讨论】:
-
这个问题更适合软件工程。
我知道分配给数组的内存会在数组超出范围时被释放,但是为什么在 C、C++ 和 Fortran 等语言中,动态数组在超出范围时不会自动被删除?
【问题讨论】:
为什么在 C、C++ 和 Fortran 等语言中,动态数组在超出范围时不会自动被删除
因为动态分配对象的生命周期不受范围限制。考虑一个分配对象然后返回指向它的指针的函数:
ObjectClass* createObject(size_t count) {
ObjectClass* ptr = malloc( sizeof(ObjectClass) );
ptr->someArraMember = calloc( sizeof(ArrayMember), count );
return ptr;
}
如果ptr 的内存在离开作用域时被释放(即当createObject 返回时),那么指针将是一个“悬空指针”,如果使用它会破坏程序的内存:
ObjectClass* createObject(size_t count) {
ObjectClass* ptr = malloc( sizeof(ObjectClass) );
ptr->someArraMember = calloc( sizeof(ArrayMember), count );
free( ptr );
return ptr; // <-- NEVER DO THIS!
}
然而,静态数组的寿命受到范围的限制,根据设计,并且通常是堆栈分配的。在执行后返回指向静态数组元素的指针离开数组的范围会导致未定义的行为(即您的程序最终会崩溃......)。
int* getStaticArrayElement(size_t i) {
int staticArray[100];
return &staticArray[i]; // <-- NEVER DO THIS!
}
请记住,C 是一种非常古老的语言(可以追溯到 1960 年代),并且被设计为很简单,因此诸如垃圾收集(太复杂)和引用计数(太昂贵)之类的东西被删除并成为程序员的责任来实现) - 另请注意,该语言早于更智能的对象生命周期分析(Go-lang 拥有)或所有权语义(如 Rust 拥有),这就是它们不可用的原因,并且考虑到 C 运行时环境尽可能最小和简单的频繁要求这意味着我们不太可能在未来的 C 语言版本中看到这些功能。
如果您想要一种语言,它可以让您拥有 C 所拥有的控制权 - 具有所有权语义等现代特性,那么请使用 Rust:https://www.rust-lang.org/
【讨论】: