关注“杜明c”,每天进步一点点
摘要内存结构
C语言和内存相关的四个函数
malloc
free
calloc
realloc
常见的错误
空指针不能访问声明
了指针不等于申请了空间
释放指针之后,仍然使用它
内存分配之后,以为其自动初始化
内存越界
内存泄漏
一个C/C++程序在内存中占用的空间分下面几个部分
代码段
静态区
BBS段
数据段
堆
栈
静态区
静态区分为读写段,只读段,储存全局变量,静态变量和字符串常量等等,由编译器管理,在程序结束后自动释放资源。
int i = 0;char *str = "hello world";static char c;
代码段
用于存放函数体的代码,是只读字段,在程序运行期间不会改变。
void print(int b){ int a = b; //A printf("%d",a);}//A,代码段将会储存 a = b;而初始化int a由编译器完成,并不储存在代码段
栈
栈区由编译器自动管理,不需要开发者操心,由于栈后进先出的特点,适合保存\恢复现场。作为储存函数局部变量的区域,超出作用域的变量将从栈中弹出。
void fun(){ int a; //栈区储存局部变量,在函数结束时释放。 int b;}//注意,栈区大小是有限的,不宜储存很大的数据,否则将会提示异常栈溢出。
堆
堆区储存由malloc函数或者new操作符分配的空间,生命周期由free和delete决定,堆区可以申请很大的储存空间,在32位平台上,理论上最大可以申请4G的空间,一些很大的数据结构,动态数组,放到堆区更合适,但是一定要注意使用过后释放资源。
void fun(){ char *str = (char*)malloc(10);//申请的空间存放在堆区}
C语言和内存相关的四个函数
使用这些函数需要声明头文件 stdlib.h
内存问题在不同环境下,效果可能不一致,本文的编译环境win10,VC6。
malloc
free
calloc
realloc
malloc
void *malloc(size_t size);//声明//size:申请的字节数
C语言里,malloc函数用于申请可用的空间,但是不保证一定申请成功,失败返回NULL。
int *p = (int *)malloc(sizeof(int)*10); //申请能容纳10位int元素的地址char *str = (char*)malloc(10); //申请能容纳10个字符的地址if(!p) //malloc不保证一定能申请到空间{ printf("申请空间失败!\n");}//注意:malloc返回的是无类型的地址,需要强制转换类型
可以用malloc申请一个0字节的内存吗?
char *p = (char*)malloc(0);//可以返回一个非零地址,但是不能在该地址读写,因为他可能会被之后申请的变量覆盖//并且释放该指针会导致出错
free
void free(void *ptr);//声明//ptr 需要释放的指针
free函数用于释放空间,只能释放由malloc申请的空间,否则将出现未知的错误。一个对象使用完毕之后,应该尽快释放,避免内存泄漏(其实说白了就是该内存空间使用完毕之后未回收 )。
void fun(char *p){...}char *str = (char*)malloc(10); //申请能容纳10个字符的地址void fun(str); //调用free(str); //使用完毕后,释放内存str = NULL; //同时将指针清空,避免再次使用已释放的内存
calloc
void *calloc(size_t nitems, size_t size);//calloc函数的声明/*nitems:要被分配的元素个数size :元素的大小*/
calloc函数用于申请空间,和malloc类似,不同之处在于calloc会设置分配的内存为零。
int* a = (int*)calloc(10, sizeof(int));free(a);
realloc
//声明void *realloc(void *ptr, size_t size);/*ptr :指向一个由malloc或者calloc申请的内存地址size:内存块的新大小,字节为单位*/
用realloc尝试重新调整之前调用 malloc 或 calloc 所分配的 ptr 所指向的内存块的大小。(简而言之,内存不够用,申请更大的空间)
char *str = (char *) malloc(15);strcpy(str, "杜明c"); //字符串复制函数printf("字符串地址:%p\n",str);str = (char *) realloc(str, 25); //重新分配空间strcat(str, "语言"); //追加字符串printf("重新分配空间后:%p\n",str);printf("str:%s\n",str); free(str);----out----字符串地址 :00883940重新分配空间后:00883940str:杜明c语言
在C++中,new,delete和 malloc,free有类似的作用
int *num = new int(5); //将整数赋值为5int *nums = new int[100]; //申请一个大小为100的整型数组空间int **nums = new int[5][6]; //二维数组delete num; //删除整数delete[] nums; //删除数组
常见的内存错误
初学者经常犯的一些错误。
空指针不能访问
//使用指针之前,附加一个判断void fun1(char *p){ if(p==NULL) return; ...}
声明了指针不等于申请了空间
struct student{ char name[10]; int age;};struct student *p;p->age = 17; //错误p = (struct student *)malloc(sizeof(struct student));//正确p->age = 17;
释放指针之后,仍然使用它
char *p = (char *)malloc(10);free(p);strcpy(p, "杜明c"); //错误
内存分配之后,以为其自动初始化
int i;while(i<10) //实际上,可能不仅仅只执行10次,i未初始化,可能为任何值{ ... i++;}
内存越界
int nums[10];int i = 0;for(;i<=10;i++){ printf("%d\n",nums[i]); //内存越界,没有nums[10]}
内存泄漏
就是该内存空间使用完毕之后未回收。
int i = 0;char *p;for(;i<=10;i++){ p = (char *)malloc(10); //申请了内存,却没有完全释放}free(p); //只释放了一次
End
杜明C语言
专注C/C++
每天进步一点点
长按关注![b40286e79d6ea5423f0a3fe9d7f84435.png](https://i-blog.csdnimg.cn/blog_migrate/30e954ac70ebd871cd8c6470f8665e9d.jpeg)
写留言