1、静态开辟内存
在函数局部内,创建的数据,在执行函数的时候会进栈操作,函数执行完毕,会执行弹栈。因此会释放栈内的成员,栈内的数据也称之为栈内成员,这种方式开辟的内存,称为静态开辟,执行完会弹栈。不会占用内存空间。
// 进栈
void staticAction() {
int arr[5]; // 静态开辟 栈区 (栈成员)
for (int i = 0; i <5; ++i) {
arr[i] = i;
printf("%d, %p\n", *(arr + i), arr + i);
}
} // 函数的末尾会弹栈(隐士):执行完毕会弹栈 会释放所有的栈成员
// 2.静态开辟。
int main() {
// int 4 * 10 = 40M
// int arr[10 * 1024 * 1024]; // 10M * 4 = 40M 会栈溢出
// int arr[1 * 1024 * 1024]; 会栈溢出
int arr[(int)(0.2 * 1024 * 1024)]; // 不会栈溢出
// 栈区:占用内存大小 最大值: 大概 2M 大于2M会栈溢出 平台有关系的
// 堆区:占用内存大小 最大值: 大概80% 40M没有任何问题,基本上不用担心 堆区很大的
// 大概80%: Windows系统 给我们的编译器给予的空间 的 百分之百八十
staticAction(); // 调用开辟20
return (0);
}
2、动态开辟内存
有时候我们需要用到动态开辟内存,比如有时候我们需要动态设置数组的大小。
使用malloc函数,可以动态开辟内存,这种方式的空间属于在堆中开辟,函数执行完毕之后,不会释放堆空间,因此我们一定要手动释放free,并把指针指向NULL。避免悬空指针。
/// 函数进栈 定义一个int arr[5]; 定义一个 int i; (静态的范畴)
// malloc 在堆区开辟的内存空间 , (动态的范畴)
// C的开发过程中,不能出现,野指针,悬空指针
void dynamicAction() {
int *p; // 野指针 没有地址的,空的
// void * 可以任意转变 int* double *
int *arr = malloc(1 * 1024 * 1024); // 堆区开辟 4M
printf("dynamicAction函数,arr自己的内存地址:%p,堆区开辟的内存地址:%p\n", &arr, arr);
// C工程师,堆区开辟的空间,必须释放
free(arr); // 释放掉
arr = NULL; // 重新指向一块内存地址00000
printf("dynamicAction函数2 堆区开辟的内存地址:%p\n", arr); // 悬空指针
}
int main() {
dynamicAction(); // 调用开辟20
return 0;
}
网友评论