函数调用模型

基本原理

函数调用模型_第1张图片

函数调用模型_第2张图片

内存四区模型和函数调用模型变量传递分析

1、一个主程序有n函数组成,c++编译器会建立有几个堆区?有几个栈区?
2、函数嵌套调用时,实参地址传给形参后,C++编译器如何管理变量的生命周期?
分析:函数A,调用函数B,通过参数传递的变量(内存空间能用吗?)

函数调用模型_第3张图片

提示学好C语言的关键

函数调用模型_第4张图片

如何建立正确的程序运行内存布局图

  • 内存四区模型&函数调用模型
  • 函数内元素
    • 深入理解数据类型和变量“内存”属性
    • 一级指针内存布局图(int *,char*)
    • 二级指针内存布局图(int ** char **)
  • 函数间
    • 主调函数分配内存,还是被调用函数分配内存
    • 主调函数如何使用被调用函数分配的内存(技术关键点:指针做函数参数)

======》学习指针的技术路线图

内存四区强化训练

01全局区训练

  • char *p1= “abcdefg”;

02 堆栈区生命周期训练

  • Char p1[]= “abcdefg”;
  • 返回基本类型
  • 返回非基本类型 

03堆栈属性训练

  • 测试heap生长方向
  • 测试stack生长方向
    • Heap、stack生长方向和内存存放方向是两个不同概念
    • 野指针
    • Malloc得到指针释放问题测试
      • free(p)
      • free(p+1),深入理解

函数调用模型_第5张图片

训练 划出内存四区

void main00()
{
	char buf[100];
	//byte b1 = new byte[100];
        int a = 10; //分配4个字节的内存 栈区也叫临时区
	int *p;//分配4个字节的内存
	p = &a; //cpu执行的代码,放在代码区
	*p = 20; 

	{
		char *p = NULL; //分配4个字节的内存 栈区也叫临时区
		p = (char *)malloc(100); //内存泄露概念
		if (p != NULL)
		{
			free(p);
		}
	}
	
	system("pause");
}

char * getstring1()
{
	char *p1 = "abcde";
	return p1;
}

// 函数返回值是字符型指针变量
char * getstring2()
{
	char *p2 = "abcde";
	return p2;
}


void main01()
{
	int i= 0;

	//指针指向谁就把谁的地址赋给指针变量。
	char *p1 = getstring1();
	char *p2 = getstring2();
	char *******    p3 = NULL; //p3 是个变量

	//指针变量和它所执行的内存空间变量是两个不同的概念
	strcmp(p1, p2);
	system("pause");
}

代码解析:静态存储区理解

#include 

char * getStr1()
{
	char *p1 = "abcdefg2";
	return p1;
}
char *getStr2()
{
	char *p2 = "abcdefg2";
	return p2;
}

void main()
{
	char *p1 = NULL;
	char *p2 = NULL;
	p1 = getStr1();
	p2 = getStr2();

	//打印p1 p2 所指向内存空间的数据
	printf("p1:%s , p2:%s \n", p1, p2);

	//打印p1 p2 的值
	printf("p1:%d , p2:%d \n", p1, p2);

	printf("hello...\n");
	system("pause");
	return ;
}

代码解析:堆栈区的理解

#define  _CRT_SECURE_NO_WARNINGS 
#include 
#include 
#include 

//堆
char *getMem(int num)
{
	char *p1 = NULL;
	p1 = (char *)malloc(sizeof(char) * num);
	if (p1 == NULL)
	{
		return NULL;
	}
	return p1;
}

//栈
//注意 return不是把内存块 64个字节,给return出来,而是把内存块的首地址(内存的标号0xaa11) ,返回给 tmp
// 理解指针的关键,是内存. 没有内存哪里的指针 
char *getMem2()
{
	char buf[64]; //临时变量 栈区存放
	strcpy(buf, "123456789");
	//printf("buf:%s\n", buf);
	return buf;
}

void main()
{
	char *tmp = NULL;
	tmp = getMem(10);
	if (tmp == NULL)
	{
		return ;
	}
	strcpy(tmp, "111222"); //向tmp做指向的内存空间中copy数据

	//tmp = getMem2();
	tmp = 0xaa11;

	printf("hello..tmp:%s.\n", tmp);
	system("pause");
	return ;
}

代码解析:堆栈的属性测试

#define  _CRT_SECURE_NO_WARNINGS 
#include 
#include 
#include 

//栈的开口向上向下,,测试 release和dubug;
//一般认为:栈开口向下 
//不管栈开口向上还是向下,buf的内存地址buf+1,永远向上的..

void main()
{
	int a;
	int b ;
	char buf[128];  //静态联邦的时候 buf所代表的内存空间的标号 就已经定义下来了....
	printf("&a:%d , &b: %d \n", &a, &b);
	system("pause");
	return ;
}

 

你可能感兴趣的:(c/c++)