内存分类:
动态内存
使用背景:
用户无法确定空间大小,或者空间太大,栈上无法分配内存时采用动态分配内存的方式分配内存。内存的分配与释放都由程序员决定
使用原则:
多数程序员采用能不用就不用的原则,原因在于动态内存的敏感性,不通程度的程序员应当遵循不同的使用原则,目的是为了更好的使程序安全运行并实现相应的功能。
优点:
提高程序的运行效率
缺点:
内存管理变的复杂
导致内存泄漏:内存分配后没有释放,导致内存空间减少的现象
导致内存耗尽:分配过多内存没有及时的释放,导致内存不够用
大型项目中内存多次分配后,释放的顺序就成了难题
静态内存
概念:
程序开始运行时,由编译器决定内存的分配,它的分配是程序开始编译时完成的,不占用cpu资源,程序中的各种变量,在编译时系统就已经为其分配了内存空间,当该变量在作用域中使用完毕之后会自动释放内存,无需程序员考虑。
优点:
减少内存资源的风险,如内存泄漏、内存耗尽等
缺点:
造成内存溢出
动态内存与静态内存的区别
- 静态内存的分配在编译时完成的,动态内存的分配在程序运行时完成的
- 静态内存的分配不占用cpu资源,动态内存的分配与释放都占用cpu的资源
- 静态内存在栈上分配的,动态内存在堆上分配的
- 动态内存分配需要指针与引用数据类型的支持,而静态内存不需要
- 静态内存的分配是在编译前就已经确定了内存块的大小,属于按计划分配,动态呢内存根据需要随时分配属于按需分配
- 静态内存的控制权限在编译器,动态内存在程序员
内存管理的基本操作
分配内存:
计算机的内存空间都是通过指针来进行访问的。
0.free()函数
函数原型
void free(void *memblock);
功能:
释放memblock的内存,原指针就会变成悬空指针,再次使用会出错
1.malloc()函数
函数原型:
void* malloc(unsigned int size);
功能:
分配长度为size字节的内存块,如果分配成功,则返回指向被分配内存的指针,否则返回NULL。
注意:
内存不再使用时要用free()函数释放内存块。
例子:
#include<stdio.h>
#include<cstdlib>
int main(){
int *buffer;
buffer = (int*)malloc(200);
*buffer = 55;
printf("释放前:%d\n",*buffer);
free(buffer);
printf("释放后:%d\n",*buffer);
}
2.calloc()函数
函数原型:
void *calloc(unsigned n,unsigned size);
函数功能:
在内存动态分配中分配一个n个长度为size的内存块,分配成功后返回指向被分配内存的指针;否则返回NULL,内存不在使用后使用free()函数释放内存。
应用场景:
可以想像成数组
#include<stdio.h>
#include<cstdlib>
int main(){
int *buffer;
buffer = (int*)calloc(2,sizeof(int));
printf("赋值:\n");
for (int i = 0; i <=10; i++)
{
*buffer++ = i;
printf("%d,",i);
}
printf("读值:\n");
for (int i = 0; i <=10; i++)
{
printf("%d,",*--buffer);
}
printf("释放内存:\n");
free(buffer);
}
3.realloc()函数
函数原型:
void*realloc(void*mem_address,unsigned int newsize);
函数功能:
调整mem_address所指向内存区域的大小为newsize长度,如果成功,则返回指向被分配内存的指针;否则返回空指针NULL,同样释放内存使用free()函数。
注意:
当参数men_address指向NULL时,其功能跟malloc()函数是一样的。
当参数newsize为0时,即要调整成长度为0,realloc的功能跟free()函数是相同的。
#include<stdio.h>
#include<cstdlib>
int main(){
char *buffer;
buffer = (char*)malloc(2);
printf("%x\n",buffer);
printf("调整\n");
buffer=(char*)realloc(buffer,12);
printf("%x\n",buffer);
free(buffer);
}
4.memset()函数
函数原型:
void*memset(void*s,char ch ,unsigned n);
函数功能:
设置s中的所有字节为ch,s数组的大小为n
可以想成字符串的初始化或者替换
#include<stdio.h>
#include<cstring>
int main(){
char buffer[] = "wellcom linux";
printf("buffer中的值%s\n",buffer);
memset(buffer,'*',strlen(buffer));
printf("buffer中的值%s\n",buffer);
}