内存管理
进程空间
源程序:源代码
程序(可执行文件):有源程序编译后的文件 进程:时间概念,可执行文件被拉起到结束的这段过程。进程可以被拉起多个。 进程空间:可执行文件被拉起,在内存中的分布情况。 进程空间的分布:stackheapdata>未初始化>初始化text
32位机最大寻址3G,
重点栈,堆栈:auto修饰的变量,谁调谁用,用完即消。不需要人工干预。(入栈与出栈的关系),栈溢出。主要用于数据的交换,为不是适用于大空间的申请使用(大数据的申请用堆)
。大小不超过10M,避免大量的递归。
发展方向:由高到低先定义的在高位上,后申明的在低位上。堆:可以存放任意类型的数据类型,但需要自己申请使用与释放。
申请:malloc();
释放:free(); 大小:大空间。 发展方向:由低到高char * p = (char*)molloc(1024*1024*1024);//加内存可解决strcpy(p,"adbksj");printf("sjdkjfk");free(p);
申请mallloc以字节为大小
基本类型的申请
int * p = (int*)malloc(1*sizeof(int));//申请int类型的4个字节的大小*p = 100;//初始化printf("*p = %d\n",*p);//100
构造类型--数组的申请:
申请和初始化的最小单位均是字节 memset(p,0,sizeof(int))初始化int arr[10];int *p = (int*)malloc(10*sizeof(int));memset(p,0,10*sizeof(int));//初始化,p:首地址,0:初始化元素,后面是大小for(int i = 0;i < 10;i++) { printf("%d\n",p[i]);//不知道的值,不能使用*p++}free(p);
calloc()
int *p = (int *)calloc(10,sizeof(int));//10个4个单元的大小for(int i = 0;i < 10;i++) { printf("%d\n",p[i]);//自动初始化了}
realloc()扩容
char * pa = (char*)malloc(10);strcpy(pa,"1234567890abcdef");//实际数据大于了申请的空间,这时候使用realloc();
char *pa = (char*)malloc(10);char *newPa;newPa = realloc(pa,20);strcpy(newPa,"1234567890abcdef");//newPa与pa有时候会不一样free(newPa);
或者
char *pa = (char*)malloc(10);pa = realloc(pa,20);strcpy(pa,"1234567890abcdef");//newPa与pa有时候会不一样free(pa);
realloc()有两种情况,一种是空间不足在后买你继续扩充,另一种是开辟的空间不足,重新开辟足够的空间,把数据复制过去。
应用模型
#include#include int main() { int *pa; int len; printf("please new len:"); scanf("%d",&len); pa = (int*)malloc(len*sizeof(int)); int oldlen = len; for(int i = 0;i
常见问题解析
错误模型一:在服务器模型中,常用到大循环,在大循环中未释放原有空间,重新申请新空间,造成原有空间内存泄漏。
while(1) { char *pa = (char*)malloc(100); printf("ooooooooooooo\n"); printf("ooooooooooooo\n"); printf("ooooooooooooo\n"); printf("ooooooooooooo\n"); printf("ooooooooooooo\n"); printf("ooooooooooooo\n"); printf("ooooooooooooo\n"); printf("ooooooooooooo\n"); printf("ooooooooooooo\n"); printf("ooooooooooooo\n"); printf("ooooooooooooo\n"); printf("ooooooooooooo\n"); printf("ooooooooooooo\n"); printf("ooooooooooooo\n"); pa = (char*)malloc(100);//前面申请之后没有释放,重新申请 //第一次申请,没有释放,在内存中占有空间,第二次给同一变量再次申请,前一次的空间没有释放。同样占有内存空间。释放要配对使用。两次使用free();也会挂机。malloc多余free会挂机,free对于malloc也会挂机。}
置空与判空
对内存使用的逻辑:申请,判空,使用,释放,常见错误:释放以后未置空为NULL再次做判空使用或者释放以后继续菲方使用。
char *pc = (char*)malloc(100);//申请if(pc == NULL) { printf("error\n");//内存里已经没有空间了 exit(-1);}strcpy(px,"afakjfklajflkfja");//使用free(pc);//释放pc = NULL;//置空
谁申请谁释放,防止多次释放
void func(char*p) { printf("%s\n",p); free(p); p = NULL;}int main() { char *p = (char*)malloc(100); if(NULL == p) { exit(-1); } strcpy(p,"adajsfkljlk"); func(p); free(p); p = NULL;//会挂机,func中无需释放,谁申请谁释放 return 0;}
开放的地址空间
void foo() { printf("p = %s\n",p);}void func() { printf("p = %s\n",p);}int main() { char *p = (char*)malloc(100); strcpy(p,"afkajfklj"); func(p); foo(p); return 0;}//p属于同一个变量,但是属于不同空间。p地址在不同的作用域中是共同开放的。
堆与栈空间的返回
栈空间不可以返回,堆空间可以返回。
1.只可以返回 2.地址也可以返回,返回来的地址不要去使用 3.谁用谁开,用完即消,不可以返回----栈 4.堆上的空间是可以返回的int func() { int a = 500; return a;}int* foo() { int a = 500; /* printf("&a = %p\n",pa);windows下不行 */ int *pa = &a; printf("&a = %p\n",pa); return pa;}int *func2() {//谁用谁开,用完即消,不可以返回----栈 int arr[100]; return arr;}int main() { int a = func();//可以返回 printf("a = %d\n",a); int *pa = foo();//地址可以返回,空间消失了。 printf("pa = %p\n",pa); 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] = '\0'; return p;}int main() { char *p = getFormatMem(100,'a');//包装好的申请 printf("p = %s\n",p); free(p);//释放, return 0;}