【基础C&C++】内存函数

C&C++内存管理 内存管理 阅读详情

 1.malloc函数

原型:extern void *malloc(unsigned int num_bytes);

  头文件:在TC2.0中可以用malloc.h或 alloc.h (注意:alloc.h 与 malloc.h 的内容是完全一致的),而在Visual C++6.0中可以用malloc.h或者stdlib.h。

  功能:分配长度为num_bytes字节的内存块

  返回值:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。

说明:关于该函数的原型,在旧的版本中malloc返回的是char型指针,新的ANSIC标准规定,该函数返回为void型指针,因此必要时要进行类型转换。void*类型可以强制转换为任何其它类型的指针。

1.1 malloc实现机制

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

1.2 malloc 和 new 比较

从函数声明上可以看出。malloc和 new 至少有两个不同: new 返回指定类型的指针,并且可以自动计算所需要大小。比如:

  int *p;

  p = new int;//返回类型为int* 类型(整数型指针),分配大小为 sizeof(int);

  或:

  int* parr;

  parr = new int [100]; //返回类型为 int* 类型(整数型指针),分配大小为 sizeof(int) * 100;

  而 malloc 则必须由我们计算要字节数,并且在返回后强行转换为实际类型的指针。

  int* p;

  p = (int *)malloc (sizeof(int));

  第一、malloc 函数返回的是 void * 类型。对于C++,如果你写成:p = malloc (sizeof(int)); 则程序无法通过编译,报错:“不能将 void* 赋值给 int * 类型变量”。所以必须通过 (int *) 来将强制转换。而对于C,没有这个要求,但为了使C程序更方便的移植到C++中来,建议养成强制转换的习惯。

  第二、函数的实参为sizeof(int) ,用于指明一个整型数据需要的大小。如果你写成:

  int* p = (int*) malloc (1);

  代码也能通过编译,但事实上只分配了1个字节大小的内存空间,当你往里头存入一个整数,就会有3个字节无家可归,而直接“住进邻居家”!造成的结果是后面的内存中原有数据内容被改写。

  malloc 也可以达到 new [] 的效果,申请出一段连续的内存,方法无非是指定你所需要内存大小。

  比如想分配100个int类型的空间:

  int* p = (int*) malloc ( sizeof(int) * 100 ); //分配可以放得下100个整数的内存空间。

  另外有一点不能直接看出的区别是,malloc 只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。

  除了分配及最后释放的方法不一样以外,通过malloc或new得到指针,在其它操作上保持一致。

  对其做一个特例补充

  char *ptr;

  if ((ptr =(char *)malloc(0)) == NULL)

  puts("Gota null pointer");

  else

  puts("Gota valid pointer");

  此时得到的是Got avalid pointer。把0赋给malloc能得到一个合法的指针。

2. calloc函数

用 法: void *calloc(unsigned n,unsignedsize);

功 能: 在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。

  跟malloc的区别:

  calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。

3. alloca

void * __cdecl alloca(size_t);

 内存分配函数,与malloc,calloc,realloc类似.

  但是注意一个重要的区别,_alloca是在栈(stack)上申请空间,用完马上就释放.

  包含在头文件malloc.h中.

         alloca不具可移植性, 而且在没有传统堆栈的机器上很难实现。

  当它的返回值直接传入另一个函数时会带来问题,因为他分配在栈上.

  由于这些原因, alloca不宜使用在必须广泛移植的程序中, 不管它可能多么有用。

4.realloc

extern void *realloc(void *mem_address, unsigned intnewsize);

 头文件:#include <stdlib.h> 有些编译器需要#include <alloc.h>,在TC2.0中可以使用alloc.h头文件

  功能:先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域,同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。

  返回值:如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NULL。 

注意:这里原始内存中的数据还是保持不变的。当内存不再使用时,应使用free()函数将内存块释放。

详细说明及注意要点

1、如果有足够空间用于扩大mem_address指向的内存块,则分配额外内存,并返回mem_address

  这里说的是“扩大”,我们知道,realloc是从堆上分配内存的,当扩大一块内存空间时, realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平。也就是说,如果原先的内存大小后面还有足够的空闲空间用来分配,加上原来的空间大小= newsize。那么就ok。得到的是一块连续的内存。

  2、如果原先的内存大小后面没有足够的空闲空间用来分配,那么从堆中另外找一块newsize大小的内存。并把原来大小内存空间中的内容复制到newsize中。返回新的mem_address指针。(数据被移动了)。老块被放回堆上。

特殊情况

  如果mem_address为null,则realloc()和malloc()类似。分配一个newsize的内存块,返回一个指向该内存块的指针。

  如果newsize大小为0,那么释放mem_address指向的内存,并返回null。

 

 

 


C&C++库函数速查手册完整指南 本文还有配套的精品资源,点击获取 简介:《C&C++库函数速查手册》为C和C++编程者提供详尽的库函数参考资料。本手册重点介绍了C语言的基础库函数,如输入输出、字符串处理、数学运算、内存管理等,以及C++在C的基础上增加的面向对象特性和STL标准模板库。通过深入理解和运用这些函数,开发者可以编写出更加高效和健壮的程序。手册附带C++库函数.chm文件,旨在帮助程序员... 阅读详情

相关推荐

中国科技大学C&C++编程课程资源包

函数在C语言中是组织程序结构的基本单元,它允许我们将复杂的问题分解为更小的、可管理的部分。函数可以接收输入参数,并可能返回结果。首先,我们来看看如何声明函数。函数声明告诉编译器函数的名称、返回类型以及参数类型,但不需要提供具体实现。声明通常放在头文件中,这样可以在多个源文件中使用该函数。// 函数声明示例// 声明一个名为max的函数,它接收两个int类型的参数并返回一个int类型的结果// 函数定义示例a : b;

weixin_42298254的博客 771

下面的代码片段的输出是什么,为什么? char *ptr; if ((ptr = (char *)malloc(0)) == NULL) puts(“Got a null pointer“);

测试代码如下: #include <stdio.h> #include <malloc.h> int main() { char *ptr; if((ptr = (char *)malloc(0)) == NULL) puts("got a null pointer\n"); else puts("got a valid pointer\n"); int.

weixin_45875586的博客 707

【Labview学习】——如何实现软件的中/英文切换

各位亲爱的小伙伴们大家好,这里是小万的labview专题,今天为大家带来的是软件的中/英文切换,在全球化的浪潮之下,各行各业发生着巨大的变化,emmm………… 以下是简单的演示图片,注意观察菜单栏和软件界面各控件的语言状态: 本次分享将分为两部分:菜单中英文切换&界面控件中英文切换 ** 菜单中英文切换 ** 1. 中/英文菜单制造 要想实现菜单的中/英文语言切换,就得做两个菜单,一个...

weixin_44827166的博客 1万+

ptr = (char *)malloc(0)

char   *ptr; if ((ptr   =   (char   *)malloc(0))   ==   NULL)   puts( "Got   a   null   pointer "); else puts( "Got   a   valid   pointer "); 上面程序在VC6.0下输出结果是:Got   a   valid   pointer 请问指针

just thinking 1409

mmpretrain学习笔记

(4)数据集路径 data_root=‘data/imagenet’–》data_root=‘data/Fruits Dataset/images’(7)适当的修改num_workers、epochs、batch_size、lr等。3、训练优化 :梯度下降算法、学习率参数、训练总轮次、学习率变化策略等。my_resnet18_8xb32_in1k.py 完整的配置文件。(6)split=‘train’、split='val’注释掉。2、数据:数据集划分、数据文件路径、批大小、数据增强策略等。

吃葡萄不吐葡萄皮 937

用Typora画流程图和序列图:Mermaid语法实战教程(含常见报错解决)

本文是一份详细的Typora与Mermaid语法实战教程,教你如何在Markdown文档中高效绘制流程图和序列图。文章涵盖从环境配置、核心语法到复杂图表构建的全过程,并重点解析了常见报错原因与解决方案,助你将可视化图表无缝融入文档工作流。

weixin_29279101的博客 299

下面的代码片段的输出是什么,为什么? char *ptr; if ((ptr = (char *)malloc(0)) == NULL) puts(“Gota null pointer“);

下面的代码片段的输出是什么,为什么? char *ptr; if ((ptr = (char *)malloc(0)) == NULL) puts(“Gota null pointer”); else puts(“Gota valid pointer”); 这个你可以先大胆猜测下,然后再用你的 编译器尝试着编译下~~ 程序如下 #include <stdio.h> #include <malloc.h> int main() { char *ptr;

路人coder 2473

简单概述人形机器人的“大脑、小脑”

原创 仲翔云人形机器人产业通2024年09月13日 19:41上海人形机器人的大脑和小脑是其控制系统的关键组成部分,它们模拟了人类大脑和小脑的功能,以实现复杂的运动控制和决策过程。

AI生成曾小健3 2069

malloc(0)返回什么地址?

问题内容:malloc(0)返回什么地址? 原讨论链接:http://community.youkuaiyun.com/expert/topicview1.asp?id=4351400 所属论坛:C语言 审核组:C/C++ 提问者:jidahyx 解决者:steedhorse 感谢:steedhorse 关键字: 答案: char *p = (char *)malloc(0); strcp

在每一个清晨,记得早起,努力追逐第一缕阳光。选一种姿态,让自己活得无可替代. 409

使用Metasploit生成木马控制Windows系统

使用Metasploit生成木马控制Windows系统

weixin_56956399的博客 2508

有了网段为什么还要有VLAN???

近几日,在学习VLAN及VXLAN方面的知识,对于产生原因做一个总结及详解。 VLAN(Virtual Local Area Network,虚拟局域网),其主要用途是用来缩小广播域,即进行隔离。 先对广播域的一个概念做如下描绘:如下图,主机A、B、C、D均连接在交换机SW1上,其中A、C同网段为192.168.252网段,而B和D同网段,为192.168.250网段。 现,假如A与C第...

dandandean_96的博客 6885

电子科大《程序设计基础(C&C++)》——(一)

第一章:绪论 1.2 软件与程序 【概念】:硬件、软件(数据和指令的集合)、程序(命令序列集合) 【认识C的程序】: # include &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;stdio.h&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;gt; int main(){ printf(&amp;amp;

云上明月的博客 1293

ui(new Ui::MainWindow)的解析

Ui命名空间的变量名,和默认空间的变量名虽然一样,但实际是两个不同的东西。所以构造函数中调用MainWindow是没问题的,因为它不是在调用自身,而是在调用其他命名空间下的另一个同名的MainWindow类。这里使用C++的成员初始化列表语法,初始化成员变量指针ui,可这里有个问题,在MainWindow的构造函数中new 一个MainWindow,这又调用一下MainWindow的构造函数,这岂不是会死循环?ui_mainwindow.h文件。mainwindow.h文件.

sinat_31608641的博客 1193

《华为C&C++语言安全规范》笔记

《华为C&C++语言安全规范》笔记 通过阅读《华为C&C++语言安全规范》1,我了解到了我在编程中很多缺失的部分。现在记录下几个要点: 规则1.1.4:严禁对指针变量进行sizeof操作 编码人员往往由于粗心,将指针当做数组进行sizeof操作,导致实际的执行结果与预期不符。 下面的代码,buffer和path分别是指针和数组,编码人员想对这2个内存进行清0操作,但由于编码人员的疏忽,第5行代码,将内存大小误写成了sizeof,与预期不符。 如果要判断当前的指针类型大小,请使用sizeof

9712

AgentScope 2.0 源码解析-工具系统解读:从内置工具到权限管控的完整实践

本文深入解析AgentScope 2.0工具系统的完整架构,覆盖内置工具集(文件读写、命令执行、搜索匹配)、MCP协议集成(STDIO/HTTP双传输、客户端封装、工作空间网关)、工具包管理与动态分组、权限引擎的多级决策机制(危险路径保护、只读识别、模式控制),以及自定义工具开发流程。通过分层架构图和时序图直观展示组件协作关系,结合安全最佳实践与故障排除指南,为开发者提供从工具使用到安全管控的全链路参考。

program哲学 568

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【C++】C&C++内存管理

内存管理是C / C++编程中至关重要的一部分,它直接影响程序的性能和稳定性。首先,了解C / C++内存分布是理解内存管理的基础。在C语言中,动态内存管理主要通过malloc、calloc、realloc和free函数来实现,而C++则引入了new和delete操作符,更方便地管理内存。对于内置类型,可以直接使用new和delete操作符,而对于自定义类型,需要实现相应的new和delete操作符以便正确地分配和释放内存。

是阿建吖! 2370

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

第五讲:C&C++内存管理

讲解C++内存管理

yi_ren_yi_xin的博客 683

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

深入理解C&C++内存管理

本篇博客涉及C&C++的内存管理,涉及malloc,calloc等C语言动态内存开辟内容的复习以及C++新增的new和delete操作符的深入分析,浅谈了内存池和堆之间的关系,希望对大家有帮助~

暴躁小吕的博客 1040

C&C++动态内存管理

C&C++动态内存管理

m0_57304511的博客 1532

C&C++内存管理【非常详细,对新手友好】

介绍C&C++内存布局,介绍堆栈概念与区别,介绍new,delete底层原理,介绍内存泄漏等等。

m0_74189279的博客 2511
上一篇: 【流式计算】如何“打败”CAP定理
下一篇: 【hadoop】map reduce的嵌套调用
indie-XinYe
博客等级 码龄19年 154粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值