C - 在内存应该已解除分配后访问可变长度数组



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

我有以下代码,它为函数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;
}

我以为可变长度数组属于自动存储类(即当我们进入包含可变长度数组的函数时,会分配可变长度数组的内存,函数退出后内存会自动释放(

所以按照这个逻辑,分配给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;
}

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

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

最新更新