动态内存开辟
来源:互联网 发布:股票分析算法 编辑:程序博客网 时间:2024/05/17 02:09
动态内存开辟的函数有malloc、realloc、calloc、free函数,接下来对每一个函数进行解释及使用,并总结出几个经典的例子巩固,以及总结常见的错误。
1.malloc & free基本使用
int main(){int* p = malloc(10 * sizeof(int));if (p == NULL){perror("error");}//...free(p);p = NULL;return 0;}
2.realloc & free基本使用int main(){int *p = malloc(12);int *ptr = NULL;if (p = NULL){perror("error");//printf("%s\n",strerror);}//...ptr = realloc(p, 120);if (ptr != NULL){p = ptr;}free(p);p = NULL;return 0;}
realloc一般用于malloc后边空间不可用,重新开辟一个空间。3.calloc & free基本使用
int main(){int *p = calloc(4, sizeof(int));//...free(p);p = NULL;return 0;}
calloc函数有两个参数,分别为个数、字节大小,并且初始化全为0注意:realloc(NULL,10) ; 等价于 malloc(10) ;
现在就几个经典的例子来讲一下动态内存开辟中经常出现的错误
典例1:
void GetMemory(char *p, int num){p = (char *)malloc(sizeof(char) * num);}void Test(void){char *str = NULL;GetMemory(str, 100);strcpy(str, "hello");}int main(){Test();system("pause:");return 0;}
程序崩溃,内存泄露。分析:
1.在Test函数内部,str以值传递的形式给GetMemory函数,GetMemory函数形参p是str的一份临时拷贝,在GetMemory函数内部用p接收动态开辟好内存地址,str并没有发生变化,等GetMemory函数返回之后,str依然保持空指针,strcpy将“hello”拷贝到NULL,访问内存出错。
2.p所指向的空间找不到了,所以存在内存泄露问题。
更改:
void GetMemory(char **p, int num){*p = (char *)malloc(sizeof(char) * num);}void Test(void){char *str = NULL;GetMemory(&str, 100);strcpy(str, "hello");printf("%s\n", str);}int main(){Test();system("pause:");return 0;}
典例2:用函数返回值来传递动态内存
char* GetMemory(int num){char*p = (char*)malloc(sizeof(char)*num);}void Test(void){char *str = NULL;str = GetMemory(100);strcpy(str, "hello");printf("%s\n", str);free(str);}int main(){Test();system("pause:");return 0;}
典例3:char *GetString(void){char p[] = "hello world";return p;}void Test(void){char *str = NULL;str = GetString();printf("%s\n", str);}int main(){Test();system("pause:");return 0;}
产生一个随机值。分析:
在Test函数内部,指针变量str是空指针,调用GetString函数,在GetString函数内部创建一个数组,里边的内容是“hello world”,p是一个局部变量,返回存放的地址,函数调用结束,内存释放,“hello world”销毁。str可以指向,但不能访问。就不能输出,“hello world”。
典例4:
int main(){char *p = (char*)malloc(100);strcpy(p, "hello");free(p);//...if (p != NULL){strcpy(p, "world");}return 0;}
分析:
p被free后其地址仍然不变,p所指的内容被释放,p就成了野指针。应该将p置为NULL。
而这里没有起到防护作用,拷贝的时候就出错。
总结(常见错误):
1.对空指针进行解引用
2.内存访问越界
3.释放非动态开辟内存
4.释放动态内存一部分
5.释放同一块动态内存多余1次
6.忘记释放
阅读全文
0 0
- 动态开辟内存总结
- 动态内存开辟
- 动态内存开辟
- 动态内存开辟
- c++动态内存开辟
- 动态内存开辟
- c语言动态开辟内存
- 二维数组动态开辟内存
- c语言动态开辟内存
- C++动态内存的开辟
- 双重指针动态开辟内存
- 动态内存开辟(c)
- c语言动态内存开辟
- 通讯录动态版(动态内存开辟)
- 数组内存的动态开辟和释放
- 链地址法+动态开辟内存 hash
- 顺序表(动态开辟内存)
- C++基础:动态内存开辟new_delete
- 根据类(不能被继承、只能在栈上/堆上创建对象)的特点设计一个类
- 【二分+2-SAT+Tarjan】POJ2723 Get Luffy Out
- Linux 帮助命令
- Codevs 3305 水果姐逛水果街Ⅱ
- 关于HTTP GET请求的url中文参数编码
- 动态内存开辟
- PostgreSQL学习手册
- git 撤销操作--git checkout、git reset、git revert、git commit -- amend
- Springmvc注解@RequestMapping(七)
- 手势密码
- cshell脚本抓取文件
- 30day框架搭建小结
- pojo 实现序列化 implements Serializable
- ubuntu16.04下配置caffe无GPU