malloc用法整理
malloc函数原型:void *malloc(unsigned int num_bytes); //分配长度为num_bytes字节的内存块
返回值是void指针,void* 表示未确定类型的指针,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者其他数据类型),可以通过类型强制转化转化为其他任意类型指针。如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。
malloc() 是动态内存分配函数,用来向系统请求分配内存空间。当无法知道内存具体的位置时,想要绑定真正的内存空间,就要用到malloc() 函数。因为malloc只管分配内存空间,并不能对分配的空间进行初始化,所以申请到的内存中的值是随机的,经常会使用memset() 进行置0操作后再使用。
与其配套的是free(),当申请到的空间不再使用时,要用free() 函数将内存空间释放掉,这样可以提高资源利用率,最重要的是,因为它可以申请内存空间,然后根据需要进行释放,才被称为“动态内存分配”!
malloc() 函数实质体现在,它有一个可以将可用内存块连接成一个长长的列表的链表,这个链表就是所谓的空闲链表。调用malloc() 函数时,它沿着链表寻找一个大到可以满足用户请求要求的连续的内存块,然后将内存块一分为二,一块的大小与用户请求的内存大小相等,另一块就是剩下的内存块。接下来,它将用户申请的那块传递给用户,将另一块返回到链表上(如果另一块有的话)。
调用free() 函数的时候,它将用户想要释放的内存块链接到空闲链上。我们可以想到,最后的空闲链链接的内存空间是一小块一小块的,如果这时用户申请分配一个较大的内存空间,那么空闲链上可能没有符合用户要求的内存块了,这个时候,malloc() 函数请求延时,并开始在空闲链上翻箱倒柜的检查各内存块,对他们进行整理,将相邻的小内存块合并成较大的内存块。如果无法获得符合要求的内存空间,那么malloc() 函数就会返回NULL,因此,调用malloc() 函数的时候,一定要判断它的返回值是否为NULL。
int *p;
p = (int*)malloc(sizeof(int) * );
//分配128个整型存储单元,并将这128个连续的整型存储单元的首地址存储到指针变量p中
double *pd = (double*)malloc(sizeof(double) * );
//分配12个double型存储单元,并将首地址存储到指针变量pd中
free(p);
free(pd);
p = NULL;
pd = NULL;
指针用完赋值NULL是一个很好的习惯。原因是:
指针free之后,free函数只是把指针指向的内存空间释放了,即内存中存储的值,但是并没有将指针的值赋为NULL,指针仍然指向这块内存。而程序判断一个指针是否合
法,通常都是使用if语句测试该指针是否为NULL来判断。所以不赋值NULL会导致指针成为所谓的“野指针”。
实例1:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void GetMemory(char *p)
{
p = (char *)malloc();
} int main(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "Hello,world");
printf("str:%s\n",str);
return ;
}
实例1程序会崩溃,打印:Segmentation fault (core dumped)
毛病出在函数GetMemory 中。编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,编译器使 _p = p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。在本例中,_p申请了新的内存,只是把 _p所指的内存地址改变了,但是p丝毫未变。所以函数GetMemory并不能输出任何东西。事实上,每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。main函数中调用GetMemory时,函数参数是str的副本不是str本身。正确程序如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void GetMemory(char *p)
{
p = (char *)malloc();
} int main(void)
{
char *str = NULL;
GetMemory(str); //不起任何作用
str = (char*)malloc();
strcpy(str, "Hello,world");
printf("str:%s\n",str);
free(str);
str = NULL; //赋值NULL,防止产生野指针
return ;
}
打印输出:str:Hello,world
实例2:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void *GetMemory(char **p, int num) //使用二级指针
{
*p = (char *)malloc(sizeof(char)*num);
} int main(void)
{
char *str = NULL;
GetMemory(&str, );
strcpy(str, "hello");
printf("str:%s\n", str);
return ;
}
打印输出: str:hello
有价值的参考网址: https://blog.csdn.net/u011217649/article/details/52853059
很牛X的参考网站:http://blog.codinglabs.org/articles/a-malloc-tutorial.html#221-内存排布
malloc用法整理的更多相关文章
- malloc用法
malloc用法三部曲:(#include<stdlib.h>下的库函数) 1.malloc eg.ps=(char*)malloc(sizeof(char)*20)的意思是,动态分配空间 ...
- Spring JdbcTemplate用法整理
Spring JdbcTemplate用法整理: xml: <?xml version="1.0" encoding="UTF-8"?> <b ...
- linq用法整理
linq用法整理 普通查询 var highScores = from student in students where student.ExamScores[exam] > score se ...
- linux学习:特殊符号,数学运算,图像与数组与部分终端命令用法整理
指令:let.expr.array.convert.tput.date.read.md5.ln.apt.系统信息 一:特殊符号用法整理 系统变量 $# 是传给脚本的参数个数 $0 是脚本本身的名字 $ ...
- #ifndef#define#endif的用法(整理)
[转] #ifndef#define#endif的用法(整理) 原作者:icwk 文件中的#ifndef 头件的中的#ifndef,这是一个很关键的东西.比如你有两个C文件,这两个C文件都in ...
- Google Guava 库用法整理<转>
参考: http://codemunchies.com/2009/10/beautiful-code-with-google-collections-guava-and-static-imports- ...
- MySQL中使用SHOW PROFILE命令分析性能的用法整理(配合explain效果更好,可以作为优化周期性检查)
这篇文章主要介绍了MySQL中使用show profile命令分析性能的用法整理,show profiles是数据库性能优化的常用命令,需要的朋友可以参考下 show profile是由Jerem ...
- Android spannableStringBuilder用法整理
Android spannableStringBuilder用法整理 分类: Android开发2013-11-29 10:58 5009人阅读 评论(0) 收藏 举报 Androidspannabl ...
- OBJECTPROPERTY用法整理
OBJECTPROPERTY用法整理 分类: 系统表与表结构 数据库管理维护2010-06-03 16:37 2783人阅读 评论(1) 收藏 举报 数据库sql serverinsertobject ...
随机推荐
- linux 打开一个文件现swap文件
转自:http://blog.csdn.net/eckelwei/article/details/17078187 有时候在用vim打开文件时提示类似以下的信息: 发现交换文件 ".expo ...
- 力扣(LeetCode) 14. 最长公共前缀
编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow" ...
- Linux 安装SSH
●centOS/redhat安装SSH 查询openssh server服务状态:systemctl status sshd 安装sshd命令: yum install openssh-server ...
- lua --- 函数的本质
1.lua中的函数是带有此法界定的第一类值. 2.创建一个函数的过程,本质上就是一个创建赋值语句的过程. 常见的创建函数的过程: function fun() print("Hello wo ...
- 十分钟带你理解Kubernetes核心概念
什么是Kubernetes? Kubernetes(k8s)是自动化容器操作的开源平台,这些操作包括部署,调度和节点集群间扩展.如果你曾经用过Docker容器技术部署容器,那么可以将Docker看成K ...
- ubuntu解压和压缩文件
.tar 解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!)———————————————.gz解压1:gun ...
- HeadFirst Ruby 第十章总结 Comparable & Enumerable
导言 这一章的标题是 Ready-Made Mixes, 也就是 Ruby 已经准备好的用于 Mix-in 的 Modules, 它们是: Comparable 和 Enumerable, Compa ...
- HTML第八章总结
Expanding your vocabulary 总述 在上一章节介绍了 CSS 的基础之后,这一章节更加具体地展开关于 CSS 的各种 rules 能够达成的效果.比如 字体:font-famil ...
- OnSen UI结合AngularJs打造”美团"APP首页 --Hybrid Ap
1.页面效果图: 演示链接地址:http://www.nxl123.cn/bokeyuan/meiTuanDemo_home/ 2.核心代码 home.html: <ons-page id=&q ...
- css图片的全屏显示代码-css3
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" ...