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 ...
随机推荐
- MySQL的正则表达式的LIKE和REGEXP区别
LIKE匹配整个列.如果被匹配的文本在列值 中出现,LIKE将不会找到它,相应的行也不被返回(除非使用 通配符).而REGEXP在列值内进行匹配,如果被匹配的文本在 列值中出现,REGEXP将会找到它 ...
- python模块(3)
1.xml:实现不同语言或程序之间进行数据交换的协议 <data> <country name="Liechtenstein"> <rank upda ...
- 基于iOS用CoreImage实现人脸识别
2018-09-04更新: 很久没有更新文章了,工作之余花时间看了之前写的这篇文章并运行了之前写的配套Demo,通过打印人脸特征CIFaceFeature的属性,发现识别的效果并不是很好,具体说明见文 ...
- 学习笔记33—graphPad画图集
1.如何去掉如下图所示的基准线(baseline): 解决办法:鼠标左键双击基准线 --->出现下图对话框,勾选Hide baseline即可. 2.画柱状图时,如何将正常人和病人的信息画在 ...
- Django - Python3 配置 MySQL
在使用 PyMySQL 之前,我们需要确保 PyMySQL 已安装 具体安装使用方法,可参考 Python3 - MySQL适配器 PyMySQL Django 如何链接 MySQL 数据库, 需要在 ...
- Python全栈开发-Day9-线程/GIL/事件/队列
本节内容 进程与线程的概念 Python threading 模块 GIL——global interpreter lock Mutex互斥锁(线程锁) Semaphore信号量 Events事件 Q ...
- (转)Nandflash读写
------------------------------------------------------------------------------------------文章1------- ...
- (转)winform之ListView
一.ListView类 1.常用的基本属性: (1)FullRowSelect:设置是否行选择模式.(默认为false) 提示:只有在Details视图该属性才有意义. (2)GridLines:设置 ...
- (7)Pool进程池
(1)# 开启过多的进程并不一定提高你的效率 因为进程池可以实现并行的概念,比Process单核并发的速度要快 # 如果cpu负载任务过多,平均单个任务执行的效率就会低,反而降低执行速度. 1个人做4 ...
- Linux 各种软件的安装-mysql篇
作为一个长期混迹在windows圈的小白,当拿到一个新的linux服务器时,有点手足无措的赶脚.但是万事开头难嘛,Just Do It! 下面记录一下自己安装各种软件时遇到的坑.这一篇先讲mysql ...