内存四区怎样分清呢

学习C++内存管理很关键

内存四区怎样分清呢

#include <iostream>

char* f1()
{
	return "abc";//返回常量内存区地址,不会销毁
}
char* f2()
{
	char* p = "abc";//返回p指针指向的常量内存区地址,常量内存区没有销毁
	return p;//销毁的是这个p所在的栈内存
}
char* f3()
{
	static char* p = "abc";//返回p指针指向的常量内存区地址,常量内存区没有销毁
	return p;//p所在的栈内存不会销毁
}
char* f4()
{
	char p[10] = "abc";//返回的是栈内存地址,这个栈内存拷贝的是常量内存区的数据
	return p;//p所在的栈内存会销毁
}
char* f5()
{
	static char p[10] = "abc";
	return p;//p数组在静态内存区,拷贝的是常量内存区中的数据
	//返回静态内存区的地址,不会销毁
}
char p1[10] = "abc";
char* f6()
{
	return p1;//p1在静态内存区,不会销毁,p1数组拷贝的是常量内存区中的数据
			//不会销毁
}
char* p2 = "abc";
char* f7()
{
	return p2;//p2是静态内存区的一个指针,
	//不会销毁,p1指向的是常量内存区中的数据
}
//----------------------------------
void t1(int a)
{
	a = 100;//修改的是t1函数中的a的值
}
void t2(int* a)
{
	*a = 100;//修改的是指针指向的变量的值
}
void t3(int& a)
{
	a = 100;//a是外面a3的别名,修改a就等同于修改a3
}
void t4(int*& a)
{
	*a = 100;
}
//----------------------------------
void g1(char* p)
{
	p = (char*)malloc(10);//局部变量p指向了堆内存
}
//传的指针的地址
void g2(char** p)
{
	//*p 就是那个指针
	*p = (char*)malloc(10);
}
void g3(char*& p)//p是p3的别名
{
	p = (char*)malloc(10);//修改p的指向就是修改p3的指向
}
//----------------------------------
char* h1()
{
	return "123";
}
char* h2()
{
	char s[100];
	return s;
}
char* h3()
{
	char* s;//返回的是一个未知的随机地址
	return s;
}
char* h4()
{
	static char* s;//返回的是0x00000000 地址
	return s;
}
char* h5()
{
	static char s[100];//返回静态内存区的地址,可以修改里面的值
	return s;
}
char* h6()
{
	char* s = (char*)malloc(123);//返回的是堆内存地址,
	return s;//这个s会销毁,但是销毁之前会把它的指向传给外面的那个p6指针
}
//----------------------------------
void main()
{
	{
		//char* p1 = h1();strcpy(p1,"aaa");//不能修改常量内存区
		//std::cout<<p1<<std::endl;
		//char* p2 = h2();strcpy(p2,"aaa");//想要操作的是一个已经销毁的内存,拷贝函数没有报错也没有拷贝成功
		//std::cout<<p2<<std::endl;//
		//char* p3 = h3();strcpy(p3,"aaa");//拷贝到一个随机的地址很有可能这个地址不允许操作,所以报错
		//std::cout<<p3<<std::endl;//
		//char* p4 = h4();strcpy(p4,"aaa"); //处未处理的异常: 0xC0000005: 写入位置 0x00000000 
		//std::cout<<p4<<std::endl;//
		//char* p5 = h5();strcpy(p5,"aaa");
		//std::cout<<p5<<std::endl;//aaa
		char* p6 = h6();strcpy(p6,"aaa");
		std::cout<<p6<<std::endl;//
	}

	{
		//char* p1 = 0;
		//g1(p1);//p1还是指向0地址的
		//strcpy(p1,"123");//报错
		//std::cout<< p1 <<std::endl;

		char* p2 = 0;
		g2(&p2);
		strcpy(p2,"123");
		std::cout<< p2 <<std::endl;//123
	
		char* p3 = 0;
		g3(p3);
		strcpy(p3,"123");
		std::cout<< p3 <<std::endl;//123
	}
	
	{
		int a1 = 0;
		t1(a1);
		std::cout<<a1<<std::endl;//0

		int a2 = 0;
		t2(&a2);
		std::cout<<a2<<std::endl;//100

		int a3 = 0;
		t3(a3);
		std::cout<<a3<<std::endl;//100

		int a4 = 0;
		int* p4 = &a4;
		//t4(&a4);
		t4(p4);
		std::cout<<a4<<std::endl;//100

		{
			int b = 100;
			int& a = b;
			//int& a = 100;
			//引用必须用变量初始化,不能用临时的值
		}
	}
	
	{
		char* p1 = f1();
		std::cout<<p1<<std::endl;//abc
		char* p2 = f2();
		std::cout<<p2<<std::endl;//abc
		char* p3 = f3();
		std::cout<<p3<<std::endl;//abc
		char* p4 = f4();
		std::cout<<p4<<std::endl;//乱码
		char* p5 = f5();
		std::cout<<p5<<std::endl;//abc
		char* p6 = f6();
		std::cout<<p6<<std::endl;//abc
		char* p7 = f7();
		std::cout<<p7<<std::endl;//abc
	}
}

char s1[128];

void k(char*& p)
{
	p = (char*)malloc(10);

	static char s[128];
	p = s;
	p = s1;
}


void test1()
{
	char* p;
	k(p);
	strcpy(p,"123abc");
	std::cout<< p <<std::endl;//要求输出123abc
}

char* k2()
{
	/*char* p1 = (char*)malloc(10);
	strcpy(p1,"123abc");
	return p1;*/

	static char s[128];
	strcpy(s,"123abc");
	return s;
}
void test2()
{
	char* p;
	p = k2();
	std::cout<< p <<std::endl;//要求输出123abc
}