C语言中的内存空间,内存分配malloc

malloc 函数详解 malloc函数和free函数详解 引言:为什么使用动态内存分配 当你声明数组时,你必须用一个编译时常量指定数组的长度。但是,数组的长度常常在运行时才知道,这是由于它所需要的内存空间取决于输入数据。例如,一个用于计算学生等级和平均分的程序可能需要存储一个班... 阅读详情

简介:

现代计算机操作系统中,重要的一个功能就是内存管理。在Linux系统中,提供了malloc函数来进行内存的分配。对应的,内存释放函数式free。

在C语言中,可以用printf函数输出变量的值,包括变量被分配的地址,%d用于输出整形,%s用于输出字符串,而%p就用于输出变量的地址值。 

C语言程序的内存空间:

C语言程序包括以下几部分:

正文段:存放由CPU执行的机器指令,通常为只读;

初始化数据段:通常将此段称为数据段,它包含了程序中需赋初值的变量。

例如,C程序中任何函数之外的说明:

float PI= 3.14f;

使此变量以初值存放在初始化数据段中;

非初始化数据段:通常将此段称为b s s段,这一名称来源于早期汇编程序的一个操作符,意思是“block started by symbol(由符号开始的块)”。在程序开始执行之前,内核将此段初始化为0。

例如,函数外的说明:

long sum[1000] ;

使此变量存放在非初始化数据段中。

栈:自动变量以及每次函数调用时所需保存的信息都存放在此段中。

每次函数调用时,其返回地址、以及调用者的环境信息(例如某些机器寄存器)都存放在栈中。然后,新被调用的函数在栈上为其自动和临时变量分配存储空间。

通过以这种方式使用栈,C函数可以递归调用。

例如,

int main() {

    int x =10;  // 栈存储

    int y = 20; // 栈存储

    return 0;

}

堆:通常在堆中进行动态存储分配,例如用malloc函数分配的地址空间。由于历史上形成的惯例,堆位于非初始化数据段顶和栈底之间。

例如,

int main() {

    int x =10;  // 栈分配

    int y = 20; // 栈分配

    char *p = (char*)malloc(256); //堆分配

    return 0;

}

用malloc在堆中分配了一块内存空间,用p保存这个内存空间的首地址,用于后续访问这块内存。但p这个变量本身是在栈中分配的。

下图,是一个典型的C语言程序内存空间分布图:

 

内存地址的测试:

1.栈上分配的地址测试:

malloc_p.c,用于打印内存地址值。

#include <stdio.h>
#include <stdlib.h>

int test1() {
	/*栈上分配,猜测,x和y的地址相邻*/
	int x = 10;
	int y = 20;

    /*预想: p = x的地址; &p =p的地址(而且,和y的地址相邻); 实际结果:和预想的一样*/
	int *p = &x; 

	printf("x=%d, &x=%p\n",x,&x);
	printf("y=%d, &y=%p\n",y,&y);
	printf("p=%p, &p=%p\n",p,&p);
	printf("\n");

	return 0;
}

int main() {
	test1();

}

编译:用gcc命令进行编译:

gcc malloc_p.c

运行结果:

x=10, &x=0x7ffeed1df88c

y=20, &y=0x7ffeed1df888

p=0x7ffeed1df88c, &p=0x7ffeed1df880

 可以看到,

一,p的值就是x的地址,而p也有自己的地址;

二,x,y,p三个变量的地址都挨着。其实都是系统在堆栈上给分配的。

2.malloc地址测试:

再看一个复杂的例子,我们加上malloc函数,再进行对比:

    /*预想:q的值和p的值离的很远,因为,q的值是在堆中分配的,q本身的地址在栈中分配*/
	char *q = (char*)malloc(256);

	printf("q=%p, &q=%p\n",q,&q);
	printf("\n");

    /*一定要进行free,否则,就有内存泄露*/
    free(q);

 运行结果:

x=10, &x=0x7ffee115788c

y=20, &y=0x7ffee1157888

p=0x7ffee115788c, &p=0x7ffee1157880

q=0x7f7f0ac05990, &q=0x7ffee1157878

可见,和我们的预想结果一样,q本身的地址和其它变量的地址都紧挨着,它们的内存都是系统在栈上分配的;而q中存储的值,和其它的变量的地址离的特别远,其实,这个地址就是malloc在堆中分配的内存地址。 

3.静态存储区的地址测试: 

 我们再加上静态全局变量和非静态全局变量来看一下:

#include <stdio.h>
#include <stdlib.h>

/*初始化数据段, 0x402000, 0x402004*/
/*m=1024, &m=0x402000
  n=2048, &n=0x402004*/
int m = 1024;
int n = 2048;

/*非初始化数据段,  0x403100*/
int arr[10];

/*静态存储,初始化数据段*/
int static MAX = 256;
int static MIN;

int test1() {
	/*栈上分配,猜测,x和y的地址相邻*/
	int x = 10;
	int y = 20;

    /*预想: p = x的地址; &p =p的地址(而且,和y的地址相邻); 实际结果:和预想的一样*/
	int *p = &x; 

	printf("x=%d, &x=%p\n",x,&x);
	printf("y=%d, &y=%p\n",y,&y);
	printf("p=%p, &p=%p\n",p,&p);

    /*预想:q的值和p的值离的很远,因为,q的值是在堆中分配的,q本身的地址在栈中分配*/
	char *q = (char*)malloc(256);
	printf("q=%p, &q=%p\n",q,&q);
    
    /*初始化数据段*/
    printf("m=%d, &m=%p\n",m,&m);
	printf("n=%d, &n=%p\n",n,&n);
	printf("\n");

    /*非初始化数据段*/
	printf("arr[0]=%d,&arr[0]=%p\n",arr[0],&arr[0]);
	printf("&arr=%p\n",&arr);
	printf("\n");

    /*静态存储,初始化数据段*/
	printf("MAX=%d, &MAX=%p\n",MAX,&MAX);
	printf("MIN=%d, &MIN=%p\n",n,&MIN);
	printf("\n");
    
    /*一定要进行free,否则,就有内存泄露*/
    free(q);

	return 0;
}

int main() {
	test1();

}

运行结果:

x=10, &x=0x7ffeef42988c

y=20, &y=0x7ffeef429888

p=0x7ffeef42988c, &p=0x7ffeef429880

q=0x7ffcd2c05990, &q=0x7ffeed011878

/*1.初始化数据段*/

m=1024, &m=0x1007de010

n=2048, &n=0x1007de014

/*2.非初始化数据段*/

arr[0]=0,&arr[0]=0x1007de020

&arr=0x1007de020

/*3.静态存储,初始化数据段*/

MAX=256, &MAX=0x1007de018

MIN=2048, &MIN=0x1007de01c

 可以看出:

1)m,n,arr,arr,MAX,MIN的地址挨着,但和前面的栈中分配的x,y,p, 以及malloc分配的堆中的内存地址,都相隔甚远;

2)其实,m,n,arr,arr,MAX,MIN这些变量,对于系统在具体分配内存的时候,并无差别。虽然我们从逻辑上将其分成了初始化数据段中,非初始化数据段中,以及静态存储的初始化数据段。


内存分配malloc,千万别忘了free。

malloc函数的使用(一) 那么动态内存是怎么样造出来的呢?这个难度有点大,这是第一个难点,后面会讲“跨函数使用动态内存”是第二个难点,而且难度更大。 malloc是一个系统函数,他是memory allocate的缩写。其中memory是“内存”的意思,allocate是“分配”的意思。所以顾名思义malloc函数功能就是“分配内存”。要调用他必须要包含头文件<stdlib.h>,他的原型为: #include... 阅读详情

相关推荐

ABAP on HANA/CDS view/AMDP 大乱炖

文章目录1. HANA的三大杀器1.1 内存式数据库1.2 多核架构1.3 列式存储1.3.1 数据压缩1.3.2 并行处理1.3.3 聚集和索引1.3.4 代码下移2. CDS 概念2.1 ABAP 开发环境2.2 OPEN SQL语句2.3 CDS 到底是啥2.4 CDS 类型2.5 创建CDS view3. CDS 实战3.1 Annotation注解3.2 Case 语句3.3 数学计算3.4 字符串表达3.5 货币转换3.6 聚集语句3.7 Join3.8 Union3.9 参数3.10 作为子C

weixin_45689053的博客 4787

C语言 两种内存分配方式 malloc函数动态分配

C中开辟内存空间的两种方式 1、静态开辟内存 这种开辟内存空间的特点是所开辟的内存是在栈中开辟的固定大小的 例如: int a; int b[5]; a是4个字节,数组b是20字节 这种方式数组在申明时必须指定其长度,因为数组的内存是在编译时分配好的。 如果我们想在程序运行时才确定一个数组的大小,静态开辟内存空间的方法是不行的 例如: int n; scanf("%d",&n); int a[n]; 这样编写会在编译时出错 2、动态开辟内存 在C中动态开辟空间有三个函数:malloc(),cal

yummy的博客 4802

用Matlab搞定Delta并联机器人运动学:从建模到正逆解完整流程(附代码)

本文详细介绍了如何使用Matlab实现Delta并联机器人的运动学分析,包括几何建模、正逆解求解及可视化验证。通过符号计算和数值迭代法,解决非线性方程组问题,并提供完整代码示例,帮助读者快速掌握Delta机器人的运动学计算与应用。

weixin_30955617的博客 177

【c语言】(动态内存分配)malloc函数解析

参数表示需要分配的内存大小(以字节为单位),函数返回值是一个指向分配的内存空间的指针。如果分配失败,则返回 NULL。接着,我们对数组进行了初始化操作,设置每个元素的值为 0。在使用完数组之后,我们调用了。函数来分配空间,将返回值强制类型转换为指向整数的指针,赋值给指针变量。是 C 语言中的一个函数,用于动态地分配内存空间。下面是一个简单的示例代码,演示了如何使用。在这个示例中,我们首先定义了一个整数变量。,表示需要分配的数组大小。函数来释放分配的内存空间。

m0_72301367的博客 2857

Dify工作流自动化:如何用Trae AI助手10倍提升你的开发效率(含避坑指南)

本文详细介绍了如何利用Trae AI助手自动化生成Dify工作流,实现开发效率的10倍提升。通过构建DSL示例库、精准需求描述和四步实战法,开发者可将重复的配置工作交给AI,快速生成可运行的工作流,并提供了关键的避坑指南。

weixin_29062865的博客 370

Ubuntu20.04安装Ceres库

ceres真难安装。

little_white138的博客 8379

malloc函数的学习

malloc函数的作用是申请分配一块连续空间。 1.头文件 malloc函数的头文件是< malloc >或者< stdlib.h >或者< alloc.h >(linux) 2.返回值 malloc若申请内存成功则会返回一个指向改该空间首地址的指针,该指针的类型为void(即可以被强制类型转化为需要的类型)。失败则返回一个NULL指针。一般情况下申请内存不会因为内存不足出现失败情况。所以失

wallacesand的博客 2450

企业级AI平台架构设计:AI应用架构师的未来趋势

企业级AI平台是AI从“实验室”走向“生产线”的关键,而AI应用架构师就是这条“生产线”的总设计师。未来,随着生成式AI、边缘计算、自治式AI的发展,架构师的角色将越来越重要——他们不仅要构建技术平台,还要连接技术与业务,让AI真正创造价值。“不要做‘只会调模型的工程师’,要做‘能解决业务问题的架构师’。因为,真正有价值的AI,从来不是“最先进的模型”,而是“能落地、能复用、能创造业务价值的平台”。愿你在企业AI转型的浪潮中,成为那个“搭建桥梁的人”——连接技术与业务,连接现在与未来。

小程序开发 973

C语言----动态内存分配(malloc calloc relloc free)超全知识点

C语言----动态内存分配(malloc calloc relloc free)超全知识点

weixin_69884785的博客 2649

SAP_MM模块采购价格确定控制简介

SAP MM模块采购价格确定控制是采购管理中的关键功能,系统通过"价格确定日期"判断条件记录有效性并带出正确价格。文章分析了四种常见业务场景及其对应的价格确定方案:普通采购订单(创建日期)、长期合同(交货日期)、特殊业务(手动输入)和接口下单(系统传入)。详细介绍了配置方法和前台操作步骤,并提供了不同业务类型对应的推荐控制方式汇总表。通过合理设置价格确定日期控制,企业可以确保采购价格准确性,满足各种复杂业务场景下价格管理的需求,从而提高采购管理效率和成本控制能力。

我小时候很黑的博客 738

ANSYS Fluent:湍流模型理论与应用

雷诺平均方程(RANS,Reynolds-Averaged Navier-Stokes equations)是湍流建模中最常用的方法。它通过将Navier-Stokes方程中的瞬时速度分解为平均速度和脉动速度,然后对这些方程进行时间平均,从而简化了湍流的计算。RANS方法的关键在于湍流闭合问题的解决,即如何准确地表示脉动速度的统计量。雷诺应力模型(RSM)是一种更高级的湍流模型,它通过求解六个雷诺应力方程来描述湍流的各向异性。RSM模型能够更准确地预测复杂的湍流流动,如旋转流和分离流,但计算成本较高。

kkchenjj的博客 2947

c语言中free作用,C语言中malloc和free的用法

在C里,内存管理是通过专门的函数来实现。另外,为了兼容各种编程语言,操作系统提供的接口通常是 C 语言写成的函数声明(Windows 本身也由C和汇编语言写成)。1 分配内存 malloc 函数需要包含头文件:#include或#include函数声明(函数原型):void *malloc(int size);说明:malloc 向系统申请分配指定size个字节的内存空间。返回类型是 void* ...

weixin_39600319的博客 452

python批量调用大模型API:多线程和异步协程

本文介绍了利用多线程技术批量调用大模型API的实现方法。核心是通过并发请求提高处理效率,主要采用线程池管理并发数量、结果聚合等技术。文章提供了一个完整的Python实现示例,包含APIBatchCaller类及其single_api_call和batch_call方法,详细解析了并发控制、错误处理等关键点,并给出了使用注意事项,包括并发数设置、重试策略和超时处理等。该方案特别适合IO密集型任务,能显著提升批量API调用的效率。

Cachel Wood的博客 760

malloc在c语言中怎么用,c语言中malloc是什么?怎么用?

malloc() 函数用来动态地分配内存空间,其原型为:void* malloc (size_t size);说明:【参数说明】size 为需要分配的内存空间的大小,以字节(Byte)计。【函数说明】malloc() 在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被初始化,它们的值是未知的。如果希望在分配内存的同时进行初始化,请使用 calloc() 函数。【返回...

weixin_42125770的博客 2483

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

malloc()与 alloc()区别

malloc()与 alloc() C语言跟内存分配方式 (1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。 (2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 (3)

兰宝的专栏 660

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

malloc

头文件:#include 定义函数:void *malloc(size_t size); 函数说明:malloc()用来配置内存空间,其大小由指定的size 决定。 返回值:若配置成功则返回一指针,失败则返回NULL。 范例 void p = malloc(1024);  //配置1k 的内存

码农崛起 507

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

malloc()与 calloc()的区别

malloc()与calloc()    C语言跟内存分配方式    1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。    2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。   

winner0703的专栏 591

malloc,calloc,realloc等内存分配函数区别

三个函数的声明分别是: void* realloc(void* ptr, unsigned newsize); void* malloc(unsigned size); void* calloc(size_t nelem, size_t elsize); 都在stdlib.h函数库内 它们的返回值都是请求系统分配的地址,如果请求失败就返回NULL malloc用于申请一段新的地

witto_sdy的专栏 618

malloc与free函数

malloc函数用来申请一块没有名字的地址,然后与数组不同的是,数组可以通过数组名来进行对地址的访问,而这个函数需要用指针指向这块地址进行访问数据,之后由free函数进行释放。

qq_73160491的博客 1504

浅谈realloc,malloc,calloc的区别

三个函数的申明分别是:  void* realloc(void* ptr, unsigned newsize);  void* malloc(unsigned size);  void* calloc(size_t numElements, size_t sizeOfElement);  都在stdlib.h函数库内 它们的返回值都是请求系统分配的地址,如果请求失败就返回NULL 

hmxiao_1983的专栏 606

malloc与free函数原型

<br />这两个和内存相关的函数都在头文件stdlib.h中,所以在应用的时候,需要包含该文件。<br />#include<stdlib.h><br /> <br />C语言中的内存分配函数:<br />void* malloc(size_t size);<br />malloc向系统申请分配制定size个字节的内存空间。返回类型是void*类型。在C或者C++中,void*类型可以强制转换为任何其他类型的指针。<br /> <br />内存释放函数:<br />void free(void* p);<

生命不止,奋斗不息! 4947

malloc与calloc的区别

malloc()与calloc()     C语言跟内存分配方式     1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。     2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存

xiaoxiaoniaoer1的专栏 612

malloc()与calloc()

malloc()与calloc()     C语言跟内存分配方式     1) 从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。     2) 在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率 很高,但

autumn20080101的专栏 871

内存分配模块相关

内存分配备忘录

tinyic的博客 379

malloc、calloc、realloc的区别

转自:http://blog.youkuaiyun.com/shuaishuai80/article/details/6140979 感谢作者! (1)C语言跟内存分配方式 从静态存储区域分配.        内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量、static变量. 在栈上创建        在执行函数时,函数内局部变量的存储单元都可以在栈上创建

BlueLoveyyt的专栏 512
上一篇: C++基础#1.1:类和对象的介绍以及简单应用
下一篇: 移动智能开发平台群雄逐鹿-塞班(Symbian),WinCE,黑莓(Blackberry),QT/Qtopia,iOS,Android
liranke
博客等级 码龄20年 4939粉丝 594原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liranke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值