前提:main调用fun1,fun1调用fun2
问题:1、每个函数变量的生命周期;
2、main函数里面的变量(分配内存)
3、fun1 fun2分配的内存,在main种能用吗?
答:关键看清分配的内存在栈、堆、全局哪个区放着,(没有内存哪有指针)内存四区模型:
heap区(堆)、 stack区(栈 )、 全局区、代码区
c语言编译器执行代码步骤:
第一步:程序代码在硬盘放着
第二步:操作系统:把硬件东西load到内存
第三步:操作系统把内存分为4个区域:1、代码区:程序的二进制代码;
2、栈区stack:编译器自动分配释放,存放函数的参数,局部变量的值,定义的临时变量,运行完毕自动释放内存;
3、堆区heap:程序员分配释放(动态内存申请与释放eg: (char *)malloc(100)),归操作系统管理,如果不释放就不会自 动回收;
4、全局区:全局变量,静态变量,常量
第四步:操作系统找到main 函数入口,进行执行
经验语句:
1、指针变量和它指向的内存空间是两个不同的概念
2、没有内存哪有指针(如果一开始定义指针的时候给指针初始化NULL,相当于把地址0x0000赋给指针变量(0x0000时操作系 统所保护的内存空间),所以此时c++编译器默认该指针还没有内存,只有真正给到它地址它才算有内存,该指针指向的地 址才会有效eg: char *p=NULL;strcpy(P,”abcd”);这句话时错的)
3、关键看清内存是在栈、堆还是全局放着?
4、主调用函数分配的内容,无论是在(堆区、栈区、全局区),都可以在被调用函数里面使用(只要指针作函数参数)
原因可参考以下函数调用模型;
5、//被调用函数分配的内存,malloc的内存(堆区)、static内存(全局区)可以让主调函数使用,但是临时区stack属性的内 存不可以;因为临时区的变量在它本身所属函数执行完毕后,该函数使用过的内存自动使用;
//在被调用函数里面malloc的内存,首地址传给调用函数有两种方法:1、return 2、指针作函数参数
6、//堆栈区的生长方向向下(即先存放的地址大),malloc生长向上(即先存放的地址小)
//heap、stack生长方向和内存存放方向是两个不同的概念,内存存放方向始终向上(eg: 数组,a[1]的地址大小肯定比a[2] 小)
补充知识点:函数调用模型
函数调用的时候,先执行的函数,最后才能执行完毕
函数调用思想<<==>>栈区stock思想(都是先进后出思想)
#define _CRT_SECURE_NO_DEPRECATE
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
char *getStr1()
{
char *p = "abcd";//c++编译器会编译优化
return p;
}
char *getStr2()
{
char *p = "abcd";//"abcd"是全局变量??;
//在c语言中全局变量会进行优化编译,即相同大小的变量会存放到同一内存空间
return p;
}
char *getStr3()
{
char buf[100];
strcpy(buf, "abcd");
return buf;
}
char *getStr4()
{
char *p = (char *)malloc(100);
strcpy(p, "abcd");
return p;
}
void main()
{
char *p1 = NULL;
char *p2 = NULL;
char *p3 = NULL;
p3 = (char*)malloc(100);//开辟到了堆区//该内存区域归操作系统管理//如果不释放此内存将无法回收//称之为内存泄漏
free(p3);
p1 = getStr1();
p2 = getStr2();
/*printf("getStr1():%s...\n", getStr1());
printf("getStr2():%s..\n",getStr2());
printf("&getStr1():%d...\n", getStr1());
printf("&getStr2():%d..\n", getStr2());
printf("getStr3():%s...\n", getStr3());*/
printf("getStr4():%s...\n", getStr3());
system("pause");
}