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用法整理的更多相关文章

  1. malloc用法

    malloc用法三部曲:(#include<stdlib.h>下的库函数) 1.malloc eg.ps=(char*)malloc(sizeof(char)*20)的意思是,动态分配空间 ...

  2. Spring JdbcTemplate用法整理

    Spring JdbcTemplate用法整理: xml: <?xml version="1.0" encoding="UTF-8"?> <b ...

  3. linq用法整理

    linq用法整理 普通查询 var highScores = from student in students where student.ExamScores[exam] > score se ...

  4. linux学习:特殊符号,数学运算,图像与数组与部分终端命令用法整理

    指令:let.expr.array.convert.tput.date.read.md5.ln.apt.系统信息 一:特殊符号用法整理 系统变量 $# 是传给脚本的参数个数 $0 是脚本本身的名字 $ ...

  5. #ifndef#define#endif的用法(整理)

    [转] #ifndef#define#endif的用法(整理)    原作者:icwk  文件中的#ifndef 头件的中的#ifndef,这是一个很关键的东西.比如你有两个C文件,这两个C文件都in ...

  6. Google Guava 库用法整理<转>

    参考: http://codemunchies.com/2009/10/beautiful-code-with-google-collections-guava-and-static-imports- ...

  7. MySQL中使用SHOW PROFILE命令分析性能的用法整理(配合explain效果更好,可以作为优化周期性检查)

    这篇文章主要介绍了MySQL中使用show profile命令分析性能的用法整理,show profiles是数据库性能优化的常用命令,需要的朋友可以参考下   show profile是由Jerem ...

  8. Android spannableStringBuilder用法整理

    Android spannableStringBuilder用法整理 分类: Android开发2013-11-29 10:58 5009人阅读 评论(0) 收藏 举报 Androidspannabl ...

  9. OBJECTPROPERTY用法整理

    OBJECTPROPERTY用法整理 分类: 系统表与表结构 数据库管理维护2010-06-03 16:37 2783人阅读 评论(1) 收藏 举报 数据库sql serverinsertobject ...

随机推荐

  1. Effective java 系列之避免过度同步和不要使用原生态类型,优先考虑泛型

    避免过度同步(67):在一个被同步的方法或代码块中,不要调用哪些被设计成被覆盖的方法或者是由客户端以函数对象的形式提供的方法(21). 有点拗口,书上提供的创建者与观察者模式,add方法太多,看得眼花 ...

  2. 雷林鹏分享:jQuery EasyUI 树形菜单 - 创建带复选框的树形菜单

    jQuery EasyUI 树形菜单 - 创建带复选框的树形菜单 easyui 的树(Tree)插件允许您创建一个复选框树.如果您点击一个节点的复选框,这个点击的节点信息将向上和向下继承.例如:点击 ...

  3. linux服务器规格查看

    性能测试前,需要确定服务器规格. 下面汇总下如何查看linux的CPU等规格 1. 查看服务器CPU个数 1)查看物理CPU个数: cat /proc/cpuinfo |grep "phys ...

  4. 协方差分析 | ANCOVA (Analysis of Covariance)

    If you are worried about leaving out covariates you could regress out them first and analyse the res ...

  5. python cook 2

    迭代器 iterator  生成器 generator 1.手动遍历迭代器 2.代理迭代 解释:将迭代操作代理到容器内部的对象上 操作:使用__iter()__,  for 循环遍历对象时,会自动调用 ...

  6. Wireshark 文件分割和合并

    # 捕获文件的基本信息. capinfos <filename> 从结果中可以看到 http.pcapng 捕获文件的基本信息,包括文件类型.封装.包大小限制.包数.文件大小及时间等. # ...

  7. JS过渡和变形效果演示(举例:鼠标滑过图片放大) --JS案例

    1.代码: <!DOCTYPE html><html><head> <meta charset="utf-8"> <title ...

  8. 如何抓取Amazon大图

    https://www.douban.com/note/277033391/ 進入到日本Amazon看到某些商品有預覽圖可以放大欣賞,當你想要右鍵下載卻發現只得到空白圖或白邊圖.縮圖.切割圖,究竟原圖 ...

  9. mysql命令查询

    含义 命令 查看gtid是否开启 show variables like '%gtid%';  查看只读信息 show global variables like "%read_only%& ...

  10. json 常用的序列化 反序列化对象 代码

    序列化对象: ---------------------------------------------------------- Person p = new Person() { Name = & ...