1.栈内存用于局部变量,临时变量,函数①运行结束时,栈内存就会自动释放,不再与函数①内的变量名绑定。但如果在下一次其他函数②的局部变量再申请栈内存时,由于栈内存循环使用的特性,此时申请到改栈内存有可能为函数①使用过的栈内存地址,且该内存仍保留函数①的写入的值(脏内存)。或者在函数①结束释放后,其他函数有申请到改栈内存,写入了其他值,此时想通过函数①的栈内存地址去访问函数①的值时,就会访问到其他函数后面写入改栈地址的其他值。
所以函数内的栈内存在函数结束释放后不允许返回调用改栈内存地址访问函数中的值。以及在函数中定义变量申请栈内存时最好对该栈内存的值进行初始化(将该脏内存洗干净在使用)
栈内存代码示例
#include<stdio.h>
int *func(void)
{
int a = 4; // a是局部变量,分配在栈上又叫栈变量,又叫临时变量
printf("&a = %p\n", &a);
return &a;
}
void func2(void)
{
int a = 33;
int b = 33;
int c = 33;
printf("in func2, &a = %p\n", &a);
}
int main(void)
{
//stack_overflow();
//stack_overflow2();
int *p = NULL;
p = func();
func2();
func2();
printf("p = %p\n", p);
printf("*p = %d.\n", *p); // 证明栈内存完了后是脏的
return 0;
}
编译结果:
&a = 0x7ffc85f7d47c
in func2, &a = 0x7ffc85f7d474
in func2, &a = 0x7ffc85f7d474
p = 0x7ffc85f7d47c
*p = 33.
2.操作系统使用堆来管理大内存,在申请和使用较大内存时,最好使用堆来管理。堆内存需要手动申请,使用完后手动释放。在申请后释放前使用该段内存,其他时段区间不应该再去访问容易造成错误。
使用malloc申请需要添加头文件#include<stdlib.h>
使用流程:申请绑定内存->检验->是否申请成功->初始化使用->释放
堆内存应用
#include <stdio.h>
#include<stdlib.h>
int main(void)
{
int *p = (int*)malloc(1000*sizeof(int));//malloc是void类型的指针函数,需强制转为需要使用的int*类型
if(NULL == p)//判断申请是否成功,malloc有返回值,成功则返回内存空间指针,失败则返回NULL
{
printf("malloc error.\n");
return -1;
}
//申请到的内存初始化并使用
*(p+0) = 1;
*(p+1) = 2;
printf("*(p+0) = %d.\n", *(p+0));
printf("*(p+1) = %d.\n", *(p+1));
free(p);
return 0;
}