栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言--内存管理

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言--内存管理

内存管理
  • 栈--------stack
  • 堆----------heap
  • 堆内存的申请与释放
    • 堆栈申请内存空间比较
    • calloc函数
    • realloc--扩容
    • 内存释放--谁申请谁释放--free
    • 常见的错误案例分析
  • 地址空间是开放的
    • 栈空间不可以返回
    • 堆空间可以返回

  • 源程序,源代码编译之后生成exe文件
  • 进程空间:可执行程序拉起之后的空间
  • stack–heap–data(uninitiated和initialized)–text 内核空间 用户空间
栈--------stack

可以存放任意类型的变量,必须是auto类型修饰的即自动类型的局部变量
方向向下,大地址在前面

堆----------heap
  • 可以存放任意类型数据,用于申请大空间,需要自己申请释放
  • malloc 以字节为单位进行申请
  • free释放空间
  • 发展方向向上,小内存
void func() //看内存的大小顺序
{
	printf("func:n");
	char *pa,*pb,*pc,*pd;
	pa = malloc(100);
	pb = malloc(100);
	pc = malloc(100);
	pd = malloc(100);
	printf("%pn",pa);
	printf("%pn",pb);
	printf("%pn",pc);
	printf("%pn",pd);
}
char *p = (char *)malloc(1000);//申请空间 malloc
free(p);
堆内存的申请与释放 堆栈申请内存空间比较
  • 函数声明 void* malloc(size_t_size) 数据类型和大小
  • memset函数 void *memset(void *str, int c, size_t n)
  • 申请基本数据类型,栈和堆空间的比较
  • malooc所属于stdlib.h
#include 
#include 
#include 
int main(void)
{
 //申请基本数据类型和数组,栈堆空间作对比。
 int a; int *p = &a;
 a = 100; printf("*p = %dn",a);
 int *pm = (int*)malloc(sizeof(int));
 if(pm == NULL) 
 return -1;
 *pm = 100;
printf("*pm = %dn",*pm);
//申请基本数据类型和数组,栈堆空间作对比。
 int array[10]; int *pa = array;
pm = (int*)malloc(10*sizeof(int));
//memset(pm,0,10*sizeof(int);
//memset(pm,0,10*sizeof(int); 此时会导致什么样的结果呢?申请都是以字节为单位
 for(int i=0; i<10; i++)
 {
 printf("%dn",pm[i]);
 }
 free(pm);
 return 0;
}
calloc函数
  • void *calloc(nmemb,size)所属于stdlib.h nmemb 所需内存单元数量size 内存单元字节数量
void *calloc(size_t_nmemb,size_t_size)
int *p = (int *)calloc(10,sizeof(int));
for(int i=0;i<10;i++)
{
	printf("%dn",p[i]);
}
realloc–扩容
#include 
#include 
#include 
int main(void)
{
 int * array = (int*)calloc(10,sizeof(int));
int * newArray = realloc(array,80);
//array = realloc(array,80);
 if(newArray == NULL)
 {
 printf("realloc 失败n");
 return -1;
 }
 for(int i=0; i<20; i++)
 {
 printf("%dn",newArray[i]);
 }
 return 0;
}
内存释放–谁申请谁释放–free
  • 申请堆内存空间之后,释放的时候一定要注意是否在申请的位置释放空间
  • free函数释放申请的堆内存
void func(char *p)
{
 strcpy(p, "American");
 printf("%sn", p);
 //free(p);   此处违反了,,谁申请谁释放的原则。
}
int main()
{
 char * p = malloc(100);
 func(p);//乍看是在func函数里面申请的,其实还是在main函数里面只不过是调用了func函数
 free(p);//因此要在main函数里面释放
 return 0;
}
int * array = (int*)calloc(10,sizeof(int));
 free(array);
常见的错误案例分析
  1. 置空与判空
    堆内存的使用逻辑:申请→判空→使用/释放→置空
    2.重复申请
    大循环中未释放原有的空间又申请新的空间造成内存泄漏
地址空间是开放的

为什么函数调用可以改变变量的值,根本原因是因为地址空间是开放的。你可以通过地址来修改改地址对应的变量的值

栈空间不可以返回
//1 数值是可以返回的
//2 地址也是可以返回
//3 栈上的空间不可以返回, 原因,随用随开,用完即消
//4 堆上的空间,是可以返回的
int func()
{
 int a = 500;
 return a;
}
int* foo()
{
 int a = 500;
 int *pa = &a;
 printf("&a = %pn",pa);
 return pa;
}
int *func2()
{
 int arr[100];
 return arr;
}
int main(int argc, char *argv[])
{
 int a = func();
 printf("a = %dn",a);
  int *pa = foo();
 printf("pa = %pn",pa);
 
 printf("%dn",*pa);
 *pa = 300;
 
 return 0;
}
堆空间可以返回
char * getFormatMem(int size,char content)
{
 char *p = (char*)malloc(size *sizeof(char));
 if(NULL == p)
 exit(-1);
 memset(p,content,size *sizeof(char)-1);
 p[size *sizeof(char)-1] = '';
 return p;
}
int main()
{
 char *p = getFormatMem(100,'a');
 printf("p = %sn",p);
 free(p);
 return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/303573.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号