- 源程序,源代码编译之后生成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("%p\n",pa);
printf("%p\n",pb);
printf("%p\n",pc);
printf("%p\n",pd);
}
char *p = (char *)malloc(1000);
free(p);
堆内存的申请与释放
堆栈申请内存空间比较
- 函数声明 void* malloc(size_t_size) 数据类型和大小
- memset函数 void *memset(void *str, int c, size_t n)
- 申请基本数据类型,栈和堆空间的比较
- malooc所属于stdlib.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int a; int *p = &a;
a = 100; printf("*p = %d\n",a);
int *pm = (int*)malloc(sizeof(int));
if(pm == NULL)
return -1;
*pm = 100;
printf("*pm = %d\n",*pm);
int array[10]; int *pa = array;
pm = (int*)malloc(10*sizeof(int));
for(int i=0; i<10; i++)
{
printf("%d\n",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("%d\n",p[i]);
}
realloc–扩容
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int * array = (int*)calloc(10,sizeof(int));
int * newArray = realloc(array,80);
if(newArray == NULL)
{
printf("realloc 失败\n");
return -1;
}
for(int i=0; i<20; i++)
{
printf("%d\n",newArray[i]);
}
return 0;
}
内存释放–谁申请谁释放–free
- 申请堆内存空间之后,释放的时候一定要注意是否在申请的位置释放空间
- free函数释放申请的堆内存
void func(char *p)
{
strcpy(p, "American");
printf("%s\n", p);
}
int main()
{
char * p = malloc(100);
func(p);
free(p);
return 0;
}
int * array = (int*)calloc(10,sizeof(int));
free(array);
常见的错误案例分析
- 置空与判空
堆内存的使用逻辑:申请→判空→使用/释放→置空 2.重复申请 大循环中未释放原有的空间又申请新的空间造成内存泄漏
地址空间是开放的
为什么函数调用可以改变变量的值,根本原因是因为地址空间是开放的。你可以通过地址来修改改地址对应的变量的值
栈空间不可以返回
int func()
{
int a = 500;
return a;
}
int* foo()
{
int a = 500;
int *pa = &a;
printf("&a = %p\n",pa);
return pa;
}
int *func2()
{
int arr[100];
return arr;
}
int main(int argc, char *argv[])
{
int a = func();
printf("a = %d\n",a);
int *pa = foo();
printf("pa = %p\n",pa);
printf("%d\n",*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] = '\0';
return p;
}
int main()
{
char *p = getFormatMem(100,'a');
printf("p = %s\n",p);
free(p);
return 0;
}
|