为什么要用malloc函数申请内存空间?

  有的程序往往在运行时才知道要动态分配多大的内存,例如: 

void foo(char *str, int n)
{
  char buf[?];
  strncpy(buf, str, n);
  ......
}

  n是由参数传进来的,事先不知道是多少,那么buf该定义多大呢?如果我们希望动态分配一块全局的内存空间,在各函数中都可以访问呢?由于全局数组无法定义成VLA,所以任然不不能满足要求,进程有一个堆空间,C标准库函数malloc可以在堆空间动态分配内存,它的底层通过brk系统调用向操作系统申请内存。动态分配的内存用完之后可以用free释放,更准确地说是归还给malloc,这样下次调用malloc时这块内存可以再次被分配。

malloc函数用法:

#include <stdlib.h>

void *malloc(size_t size);//返回值:成功返回所分配内存空
void free(void *ptr);

  malloc的参数size表示要分配的字节数,如果分配失败(可能是由于系统内存耗尽)则返回NULL。由于malloc函数不知道用户拿到这块内存要存放什么类型的数据,所以返回通用指针void *,用户程序可以转换成其它类型的指针再访问这块内存。malloc函数保证它返回的指针所指向的地址满足系统的对齐要求,例如在32位平台上返回的指针一定对齐到4字节边界,以保证用户程序把它转换成任何类型的指针都能用。动态分配的内存用完之后可以用free释放掉,传给free的参数正是先前malloc返回的内存块首地址。

  例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h> typedef struct {
int number;
char *msg;
} unit_t; int main(void)
{
unit_t *p = malloc(sizeof(unit_t));
if (p == NULL) { printf("out of memory\n");
exit(1);
} p->number = 3;
p->msg = malloc(20); strcpy(p->msg, "Hello world!");
printf("number: %d\nmsg: %s\n", p->num>msg); free(p->msg);
free(p); p = NULL;
return 0;
}

内存泄露:

  简单的程序即使不用free释放内存也可以,因为程序退出时,整个进程地址空间都会释放,包括堆空间,该进程占用的所有内存都会归还给操作系统。但如果一个程序长年累月运行(例如网络服务器程序),并且在循环或递归中调用malloc分配内存,则必须有free与之配对,分配一次就要释放一次,否则每次循环都分配内存,分配完了又不释放,就会慢慢耗尽系统内存,这种错误称为内存泄漏。另外,malloc返回的指针一定要保存好,只有把它传给free才能释放这块内存,如果这个指针丢失了,就没有办法free这块内存了,也会造成内存泄漏。

  

为什么要用mallloc的更多相关文章

  1. 函数返回多个值(c/c++)

    当我们在处理一个数组的时候常常会碰到这样的问题:输入一个数组,和数组的一个元素,返回该元素所在行数和列数.这样就需要返回多组两个值,且组数不定.上述类型的函数在c语言程序里面存在两个问题.第一,函数只 ...

  2. 以冒泡排序为例--malloc/free 重定向stdin stdout

    esort.c 代码如下,可关注下mallloc/free,freopen重定向的用法,排序为每轮将最小的数放在最前面: #include<stdio.h> #include<mal ...

  3. 对c语言中malloc和free函数的理解

    最近在复习c语言的时候再次用到了malloc函数和free函数,此处着讲解一下自己对这两个函数的理解和认识. 一. malloc函数和free函数的基本概念和基本的用法 对于malloc函数: 1.  ...

  4. c/c++面试题(5)(c++重要的概念详解)

    1.C++面向对象的三大特征? 1)封装:将客观事物封装成抽象的类,并且设计者可以对类的成员进行访问控制权限控制. 这样一方面可以做到数据的隐藏,保护数据安全;另一方面,封装可以修改类的内部 实现而不 ...

  5. 24小时学通Linux内核之内存管理方式

    昨天分析的进程的代码让自己还在头昏目眩,脑子中这几天都是关于Linux内核的,对于自己出现的一些问题我会继续改正,希望和大家好好分享,共同进步.今天将会讲诉Linux如何追踪和管理用户空间进程的可用内 ...

  6. malloc free 和new delete区别

    从网上看的学习之 1. malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符,与"+“.”-“.”*“.”/“有一样的地位. 2. new/delete是 ...

  7. free() 是如何释放不同内存区块大小的指针?

    最初是在知乎上看到这个问题的C++ delete[] 是如何知道数组大小的?,我也挺好奇,所以就作了一番工作. 申请内存时,指针所指向区块的大小这一信息,其实就记录在该指针的周围看下面这段代码: #i ...

  8. stl中的空间配置器

    一般我们习惯的c++内存配置如下 class Foo { ... }; Foo* pf = new Foo; delete pf; 这里的new实际上分为两部分执行.首先是先用::operator n ...

  9. 十天学Linux内核之第三天---内存管理方式

    原文:十天学Linux内核之第三天---内存管理方式 昨天分析的进程的代码让自己还在头昏目眩,脑子中这几天都是关于Linux内核的,对于自己出现的一些问题我会继续改正,希望和大家好好分享,共同进步.今 ...

随机推荐

  1. bootstrap下拉框式标签页

    <ul id="myTab" class="nav nav-tabs"> <li class="active"> & ...

  2. Socket()与WSASocket()的区别

    socket()   创建一个通讯端点并返回一个套接口.但是在socket库中例程在应用于阻塞套接口时会阻塞.     WSASocket()的发送操作和接收操作都可以被重叠使用.接收函数可以被多次调 ...

  3. 《剑指offer》面试题22—栈的压入、弹出序列

    <程序员面试宝典>上也有经典的火车进站问题,类似. 如果12345是压栈顺序,序列45321可能是出栈顺序,但序列43512不可能. 规律:对序列中任意元素n,排在n后且比n小的元素一定是 ...

  4. IOSerialize,xml和json,soap序列化器,二进制序列化器,XML序列化器,文件 检查、新增、复制、移动、删除

    1 文件夹/文件 检查.新增.复制.移动.删除,2 文件读写,记录文本日志/读取配置文件3 三种序列化器4 xml和json1.文件夹/文件 检查.新增.复制.移动.删除,2 文件读写,记录文本日志/ ...

  5. poj 2049(二分+spfa判负环)

    poj 2049(二分+spfa判负环) 给你一堆字符串,若字符串x的后两个字符和y的前两个字符相连,那么x可向y连边.问字符串环的平均最小值是多少.1 ≤ n ≤ 100000,有多组数据. 首先根 ...

  6. 简述RadioGroup和RadioButton的使用

    简述RadioGroup和RadioButton的使用 在项目中有身份选择的选项,需要用到RadioGroup和RadioButton,这里做个记录,和大家交流一下. 话不多说,一起看代码 XML代码 ...

  7. HTML5math标签

    HTML5 MathML 一.HTML5 可以在文档中使用 MathML 元素,对应的标签是 <math>...</math> . MathML 是数学标记语言,是一种基于XM ...

  8. day9函数作业详解

    1.day9题目 1,整理函数相关知识点,写博客. 2,写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者. 3,写函数,判断用户传入的对象(字符串.列表.元组 ...

  9. js 去除字符串空白符

    var a="      123456" varb=a.replace(/(^\s*)/g, "");

  10. C++文件操作方法小结

    - 获取文件句柄 - fopen, fclose fopen(filename, opentype): 按照opentype的方式打开指定文件,打开失败返回NULL,否则返回文件句柄. 打开类型的属性 ...