- 栈--------stack
- 堆----------heap
- 堆内存的申请与释放
- 堆栈申请内存空间比较
- calloc函数
- realloc--扩容
- 内存释放--谁申请谁释放--free
- 常见的错误案例分析
- 地址空间是开放的
- 栈空间不可以返回
- 堆空间可以返回
- 源程序,源代码编译之后生成exe文件
- 进程空间:可执行程序拉起之后的空间
- stack–heap–data(uninitiated和initialized)–text 内核空间 用户空间
可以存放任意类型的变量,必须是auto类型修饰的即自动类型的局部变量
方向向下,大地址在前面
- 可以存放任意类型数据,用于申请大空间,需要自己申请释放
- 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
#includecalloc函数#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; }
- 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内存释放–谁申请谁释放–free#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函数释放申请的堆内存
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);常见的错误案例分析
- 置空与判空
堆内存的使用逻辑:申请→判空→使用/释放→置空
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;
}



