为什么在许多语言中我们必须取消分配动态数组而不是静态数组?

时间:2018-07-07 23:59:31

标签: arrays memory dynamic

我了解到,当数组超出范围时,分配给数组的内存将被释放,但是为什么在C,C ++和Fortran等语言中,超出范围时动态数组不会自动被删除?

1 个答案:

答案 0 :(得分:3)

  

为什么在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年代),并且被设计为简单的语言,因此诸如Garbage Collection(太复杂)和reference-counting(太昂贵)之类的东西被删除,成为程序员实现的责任。 -还请注意,该语言早于更智能的对象生存期分析(Go-lang具有)或所有权语义(如Rust具有),这就是为什么它们不可用的原因,并且经常要求C运行时环境尽可能地最小化和简单化意味着我们不太可能在将来的C语言版本中看到这些功能。

如果您想要一种语言来赋予C所拥有的控制权-具有所有权语义等现代功能,请使用Rust:https://www.rust-lang.org/