Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在释放可变长度数组的内存后访问该数组_C_Memory_Variable Length Array_Automatic Storage - Fatal编程技术网

C 在释放可变长度数组的内存后访问该数组

C 在释放可变长度数组的内存后访问该数组,c,memory,variable-length-array,automatic-storage,C,Memory,Variable Length Array,Automatic Storage,我目前正在研究可变长度阵列和自动存储 我有以下代码,为函数vla中的可变长度数组myArray分配内存,并从函数返回指向可变长度数组的指针 #include <stdio.h> int * vla(int n){ int myArray[n]; myArray[0] = 10; myArray[1] = 11; int * pointerToInt = myArray; return pointerToInt; } int main(v

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

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

#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;
}
#包括
int*vla(int n){
int myArray[n];
myArray[0]=10;
myArray[1]=11;
int*pointerPoint=myArray;
返回点;
}
内部主(空){
int*pointerpoint=vla(10);
printf(“%d,%d”,pointerToInt[0],pointerToInt[1]);//打印10,11
返回0;
}
我认为可变长度数组属于自动存储类(即,当我们进入包含可变长度数组的函数时,将分配可变长度数组的内存,并且在函数退出后自动释放内存)

因此,根据这个逻辑,分配给
myArray
可变长度数组的内存在我们从
vla
方法返回后被释放,但是我怎么还能正确访问可变长度数组的第一个和第二个元素呢


是否定义了此行为?或者是未定义的行为恰好起作用?

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;
}
#包括
int*vla(int n,int a,int b){
int myArray[n];
myArray[0]=a;
myArray[1]=b;
int*pointerPoint=myArray;
返回点;
}
内部主(空){
int*pointerpoint=vla(10,10,11);
vla(10,20,21);//过写堆栈
printf(“%d,%d”,pointerToInt[0],pointerToInt[1]);//打印20,21
返回0;
}

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

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

这是未定义的行为,就像
myArray
是正常的固定大小的arrayYep,未定义的行为发生在工作中一样。myArray是在堆栈内存上创建的堆栈/自动变量。记住记忆总是存在的。它只是根据分配和解除分配由不同的指针拥有。您仍然可以访问相同值的原因是同一块内存没有分配给另一个指针,也没有被覆盖。请参阅下面的完整答案。