看了就懂!有眼睛就行!静态内存分配与动态内存分配,栈与堆,自动释放与手动释放,malloc与free。

静态内存

  1. 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
  2. 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
  3. 从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活,但问题也最多。因此,试图返回一个栈上分配的内存将会引发未知错误。

来看一个图会很好理解:
在这里插入图片描述
实际上普通的局部变量是在栈区分配空间的,栈区的特点是在上面创建的变量出了作用域就销毁。
但是被static修饰的变量存放在数据段(静态区),数据段的特点是在上面创建的变量,直到程序结束才销毁所以生命周期变长。
来两个例子对比一下:
栈区开辟的时候:
在这里插入图片描述
数据在静态数据区的时候,
在这里插入图片描述
数据在只读常量区的时候:
在这里插入图片描述

动态内存

在标准C语言上,使用malloc等内存分配函数获取内存既是从堆中分配内存,而在一个函数体中例如定义一个数组之类的操作是从栈中分配内存。

char *GetMemory3(void)
{
    
    
	char *q = "hello world!";
	char *p = NULL;
	p=(char*)malloc(20);
	if ( NULL != *p )
	{
    
    
		for (int i = 0; i < 20; i++)
		{
    
    
			*(p + i) = *(q + i);
		}
	}
	//free(p);
	return p;
}
int main()
{
    
    
	char *str =GetMemory2();
	printf("%s\n", str);
	system("pause");
}

char * p这个p指针是存储在栈中的,但它的内容是你malloc的堆内存的地址,return p时,不是返回p的地址,而是p指向的地址内容.这个时候,由于p指向的地址内容是用malloc在堆上分配的,所以是有效的.

动态内存堆,C++中由new和delete来分配和释放,C中由malloc和free来分配和释放,它的生命周期是动态的,可以由程序员来创建和销毁。当然程序结束自动释放。

return p;的时候会在内存中产生一个匿名的指针,子函数运行结束p变量消亡,运行语句char *str = GetMemory();
此时匿名指针变量赋值给str指针。
至于内存空间,由于是在堆中申请所以没有自动的释放,则会在程序结束才被释放,也就是在free之前,该空间一直存在。
有几个例子可以看看,链接在这里:
https://blog.csdn.net/Zhou000815/article/details/110493077

猜你喜欢

转载自blog.csdn.net/Zhou000815/article/details/110533540
今日推荐