在其内存应该被释放后访问可变长度数组

时间:2018-06-07 08:09:15

标签: c memory variable-length-array automatic-storage

我目前正在研究可变长度阵列和自动存储。

我有以下代码为函数myArray内的可变长度数组vla分配内存,并从函数返回指向可变长度数组的指针。

#include <stdio.h>

int * vla(int n){
    int myArray[n];

    myArray[0] = 10;
    myArray[1] = 11;

    int * pointerToInt = myArray;
    return pointerToInt;
}

int main(void){

    int * pointerToInt = vla(10);

    printf("%d, %d", pointerToInt[0], pointerToInt[1]); // prints 10, 11

    return 0;
}

我认为可变长度数组属于自动存储类(即当我们输入包含可变长度数组的函数时,将分配可变长度数组的内存,并且在函数退出后自动释放内存) / p>

所以根据这个逻辑,在我们从myArray方法返回后,分配给vla可变长度数组的内存被释放,但为什么我仍然可以正确访问变量的第一个和第二个元素长度数组?

是否定义了此行为?或者它是不恰当的行为,恰好有效吗?

2 个答案:

答案 0 :(得分:1)

myArray是在堆栈内存上创建的堆栈/自动变量。记住记忆永远存在。它仅由基于分配和释放的不同指针所拥有。您仍然可以访问相同值的原因是,同一块内存尚未分配给另一个指针而未被覆盖。

评估它。创建另一个从堆栈分配相同金额但放置不同值的函数。或者在同一个函数中添加参数,并使用不同的值调用两次。然后你会看到差异。

#include <stdio.h>

int * vla(int n, int a, int b){
    int myArray[n];

    myArray[0] = a;
    myArray[1] = b;

    int * pointerToInt = myArray;
    return pointerToInt;
}

int main(void){

    int * pointerToInt = vla(10, 10, 11);
    vla(10, 20, 21); // over write stack

    printf("%d, %d", pointerToInt[0], pointerToInt[1]); // prints 20, 21

    return 0;
}

顺便说一下从vla返回堆栈内存不是一个好主意。使用malloc函数族从堆中分配动态内存。

答案 1 :(得分:1)

您仍然可以正确访问变量长度数组的第一个和第二个元素,因为您要将myArray的基址分配给pointerToInt。自动变量只在块内有生命,但在这个程序中我们使用指针来访问内存中的数据,只要堆栈的那部分没有分配给任何其他程序,我们就可以访问那部分堆栈。如果堆栈的那部分被分配给某个其他进程,我们将在尝试访问未授权的内存时出现分段错误