malloc函数

编辑 锁定 同义词 malloc一般指malloc函数

 
malloc函数是一种分配长度为num_bytes字节的内存块的函数,可以向系统申请分配指定size个字节的内存空间。malloc的全称是memory allocation,中文叫动态内存分配,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存。
返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以通过类型转换强制转换为任何其它类型的指针。
 
中文名
动态内存分配
外文名
memory allocation
简    称
malloc
原    型
extern void *malloc
头文件
stdlib.h

malloc函数函数定义

编辑

malloc函数原型

1
extern void *malloc(unsigned int num_bytes);

malloc函数头文件

1
2
3
#include <stdlib.h>
或者
#include <malloc.h>

malloc函数函数声明

1
void *malloc(size_t size);
备注:void* 表示未确定类型的指针,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者其他数据类型)。

malloc函数返回值

如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。函数返回的指针一定要适当对齐,使其可以用于任何数据对象

malloc函数说明

关于该函数的原型,在以前malloc返回的是char指针,新的ANSIC标准规定,该函数返回为void型指针,因此必要时要进行类型转换。

malloc函数相关函数

malloc函数与new的区别

编辑

从本质上来说,malloc(Linux上具体实现可以参考man malloc,glibc通过brk()&mmap()实现)是libc里面实现的一个函数,如果在source code中没有直接或者间接include过stdlib.h,那么gcc就会报出error:‘malloc’ was not declared in this scope。如果生成了目标文件(假定动态链接malloc),如果运行平台上没有libc(Linux平台,手动指定LD_LIBRARY_PATH到一个空目录即可),或者libc中没有malloc函数,那么会在运行时(Run-time)出错。new则不然,是c++的关键字,它本身不是函数。new不依赖于头文件,c++编译器就可以把new编译成目标代码(g++4.6.3会向目标中插入_Znwm这个函数,另外,编译器还会根据参数的类型,插入相应的构造函数)。
在使用上,malloc 和 new 至少有两个不同: new 返回指定类型的指针,并且可以自动计算所需要大小。比如:
1
2
3
int *p;
p = new int;
//返回类型为int *类型(整数型指针),分配大小为sizeof(int);
或:
1
2
3
int *parr;
parr = new int[100];
//返回类型为int *类型(整数型指针),分配大小为sizeof(int) * 100;
而 malloc 则必须要由我们计算字节数,并且在返回后强行转换为实际类型的指针
1
2
3
4
5
6
7
int *p;
p = (int*)malloc(sizeof(int) * 128);
//分配128个(可根据实际需要替换该数值)整型存储单元,
//并将这128个连续的整型存储单元的首地址存储到指针变量p中
double *pd = (double*)malloc(sizeof(double) * 12);
//分配12个double型存储单元,
//并将首地址存储到指针变量pd中
第一、malloc 函数返回的是 void * 类型。
对于C++,如果你写成:p = malloc (sizeof(int)); 则程序无法通过编译,报错:“不能将 void* 赋值给 int * 类型变量”。
所以必须通过 (int *) 来将强制转换。而对于C,没有这个要求,但为了使C程序更方便的移植到C++中来,建议养成强制转换的习惯。
第二、函数的实参为 sizeof(int) ,用于指明一个整型数据需要的大小。
在Linux中可以有这样:malloc(0),这是因为Linux中malloc有一个下限值16Bytes,注意malloc(-1)是禁止的;但是在某些系统中是不允许malloc(0)的。
在规范的程序中我们有必要按照这样的格式去使用malloc及free:
1
2
3
4
5
6
7
8
9
10
type *p;
if(NULL == (p = (type*)malloc(sizeof(type))))
/*请使用if来判断,这是有必要的*/
{
    perror("error...");
    exit(1);
}
.../*其它代码*/
free(p);
p = NULL;/*请加上这句*/
malloc 也可以达到 new [] 的效果,申请出一段连续的内存,方法无非是指定你所需要内存大小。
比如想分配100个int类型的空间:
1
2
int *p = (int*)malloc(sizeof(int) * 100);
//分配可以放得下100个整数的内存空间。
另外有一点不能直接看出的区别是,malloc 只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。
除了分配及最后释放的方法不一样以外,通过malloc或new得到指针,在其它操作上保持一致。
对其做一个特例补充
1
2
3
4
5
char *ptr;
if((ptr = (char*)malloc(0)) == NULL)
    puts("Gotanullpointer");
else
    puts("Gotavalidpointer");
此时得到的是Got a valid pointer。把0赋给malloc能得到一个合法的指针

malloc函数工作机制

编辑

malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块。然后,将该内存块一分为二(一块的大小与用户请求的大小相等,另一块的大小就是剩下的字节)。接下来,将分配给用户的那块内存传给用户,并将剩下的那块(如果有的话)返回到连接表上。调用free函数时,它将用户释放的内存块连接到空闲链上。到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段,那么空闲链上可能没有可以满足用户要求的片段了。于是,malloc函数请求延时,并开始在空闲链上翻箱倒柜地检查各内存片段,对它们进行整理,将相邻的小空闲块合并成较大的内存块。如果无法获得符合要求的内存块,malloc函数会返回NULL指针,因此在调用malloc动态申请内存块时,一定要进行返回值的判断。
Linux Libc6采用的机制是在free的时候试图整合相邻的碎片,使其合并成为一个较大的free空间。

malloc函数程序示例

编辑

malloc函数正常程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
typedef struct data_type{
 
 
    int age;
     
 
    char name[20];
    
 
}data;
 
 
data*bob=NULL;
   
     
bob=(data*)malloc(sizeof(data));
 
 
if(bob!=NULL)
{
 
 
    bob->age=22;
         
 
    strcpy(bob->name,"Robert");
    
         
    printf("%sis%dyearsold\n",bob->name,bob->age);
 
 
}
    
     
else
 
{
 
    printf("mallocerror!\n");
         
    exit(-1);
    
}
     
     
free(bob);
 
bob=NULL;

malloc函数内存泄漏实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
例1:
#include <stdio.h>
#include <malloc.h>
#define MAX 100000000
 
int main(void)
{
    int *a[MAX] = {NULL};
    int i;
    for(i=0;i<MAX;i++)
    {
    a[i]=(int*)malloc(MAX);
    }
    return 0;
}
例2:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include "stdio.h"
 
#include "malloc.h"//malloc()函数被包含在malloc.h里面
 
 
int main(void)
{
 
    char *a = NULL;//声明一个指向a的char*类型的指针
         
    a = (char*)malloc(100*sizeof(char));//使用malloc分配内存的首地址,然后赋值给a
 
    if(!a)//如果malloc失败,可以得到一些log
         
    {
        perror("malloc");
        return -1;
    }
 
    sprintf(a,"%s","HelloWorld\n");//"HelloWorld\n"写入a指向的地址
     
    printf("%s\n",a);//输出用户输入的数据
     
    free(a);//释放掉使用的内存地址
 
    return 0;//例2有无内存泄露?
  
}
 
注:例1:对malloc申请之后没有检测返回值;例2:检测malloc返回值条件有误(例2是对的吧?)。

C语言-malloc的更多相关文章

  1. C语言malloc()函数:动态分配内存空间

    头文件:#include <stdlib.h> malloc() 函数用来动态地分配内存空间(如果你不了解动态内存分配,请查看:C语言动态内存分配及变量存储类别),其原型为:void* m ...

  2. C语言malloc和free实现原理

    以下是一段简单的C代码,malloc和free到底做了什么? int main() { char* p = (char*)malloc(32); free(p); return 0; } malloc ...

  3. (转)C语言malloc()与free()的使用

    如何使用 malloc 函数 本文为转载内容,原文地址请点击 不要莫名其妙,其实上面这段小小的对话,就是malloc的使用过程.malloc是一个函数,专门用来从堆上分配内存.使用malloc函数需要 ...

  4. C语言malloc函数为一维,二维,三维数组分配空间

    c语言允许建立内存动态分配区域,以存放一些临时用的数据,这些数据不必在程序的声明部分定义,也不必等到函数结束时才释放,而是需要时随时开辟,不需要时随时释放,这些数据存储在堆区.可以根据需要,向系统申请 ...

  5. C语言 malloc函数

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.                                                 ...

  6. C语言 malloc()与sizeof运算的盲点

    //malloc()与sizeof运算的盲点 #include <stdio.h> #include <stdlib.h> #include <string.h> ...

  7. C语言 malloc calloc realloc alloc 在分配内存时的 区别

    malloc : 向堆申请分配内存,不初始化 calloc  : 向堆申请分配内存,初始化为0 realloc:  向堆申请分配内存,可调整大小 alloc   :   向栈申请内存,不需手动释放

  8. C语言 malloc、calloc、realloc的区别

    三个函数的申明分别是: void* malloc(unsigned size); void* realloc(void* ptr, unsigned newsize); void* calloc(si ...

  9. 数据结构复习之C语言malloc()动态分配内存概述

    #include <stdio.h> #include <malloc.h> int main(void) { ] = {, , , , }; // 计算数组元素个数 ]); ...

随机推荐

  1. Java匹马行天下之JavaSE核心技术——工具类

    Java匹马行天之JavaSE核心技术——工具类 一.Object类 java.lang.ObjectObject类是所有类直接或间接的父类 常用的方法: toString():以字符串形式返回对象的 ...

  2. SpringMVC重要注解 @ControllerAdvice

    @ControllerAdvice,是Spring3.2提供的新注解,从名字上可以看出大体意思是控制器增强.让我们先看看@ControllerAdvice的实现: package org.spring ...

  3. RabbitMQ高级面试题

    本文涉及:投递失败的消息怎么处理.如何实现延时队列.如何指定消息的优先级.消息的持久化是如何实现的.如何保证消息不丢失 投递失败的消息怎么处理 首先投递失败存在如下两个情况 当交换器无法根据自身的类型 ...

  4. MySQL查询——select

    SELECT select的完整语法: select col1, col2,... # 业务查询的字段 from table_name # 选取的哪张表 [where single_condition ...

  5. Python中itertools.groupby分组的使用

    Python中itertools.groupby分组的使用 有时候我们需要给一个列表按照某个属性分组,可以借助groupby来实现. 比如:一下列表我想以严重程度给它分组,并求出每组的元素个数. fr ...

  6. 【转】fastjson-1.2.47-RCE

    Fastjson <= 1.2.47 远程命令执行漏洞利用工具及方法,以及避开坑点 以下操作均在Ubuntu 18下亲测可用,openjdk需要切换到8,且使用8的javac > java ...

  7. 实体类id的几种生成方式

    @Id// @GeneratedValue(strategy = GenerationType.AUTO) // 自增// @GeneratedValue(strategy = GenerationT ...

  8. youtube-dll工具使用,很好用!!

    最近喜欢上youtube-dll这个插件,下载东西真的很好用,墙裂推荐,github地址如下 https://github.com/ytdl-org/youtube-dl 安装 1.Linux 1.1 ...

  9. nginx无网络启动失败——proxy_pass域名DNS解析出错

    问题: nginx启动或者reload的时候,会对proxy_pass后面的域名进行DNS解析,如果解析失败,启动就会失败或者reload失败. 我们是to B的产品,客户的环境可能是不通公网的,因此 ...

  10. Designing Data-Intensive Applications笔记

    <Designing Data-Intensive Applications>书看完很久了,前段时间陈皓来公司技术分享也推荐了这本书.读起来酣畅淋漓,写篇系统总结的意愿强烈,无耐内容属实太 ...