• 首页
  • 做网站
  • 做推广
  • 做电商
  • 成功案例
  • 服务支持
  • 解决方案
  • 关于中企
控制台
登录
退出
注册会员
数字门户
通用版
全行业全场景的企业建站
内贸营销版
自动化营销网站
全球营销版
企业海外获客的外贸网站
个性化场景定制服务
安全稳定.高性价比.个性化定制网站
行业解决方案版
数字门户·行业解决方案版
AI友好性服务
与AI共生,帮助企业建立AI可信身份
推荐购买
企业域名
迈入互联网的第一步
企业邮箱
随时随地,全球畅邮
视觉设计类
VR全景 | 图片拍摄 | 视频制作
网站安全类
SSL证书 | 等保认证
成功案例
核心必备
全球SEO
以内容建立长效获客路径
百度首屏展位
优质流量独享,抢占百度首屏位置
Yandex推广
东欧市场获客利器
Google海外推广
外贸必备,出海利器
推荐购买
一站式企业出海
让全球客户主动找上门
成功案例
核心必备
全网商城
全渠道在线做生意
移动商城
网上开店不操心
推荐购买
零售行业OMO解决方案
电商全场景实现流量聚合变现, 用户沉淀复购
全场景电商电商解决方案
商城周边应用
粉丝分销、社区团购、活动营销等营销工具
成功案例
帮助中心
数字门户产品服务保障 服务中心 设计师 信息化讲堂 常见服务问题
实战应用
产品剖析 律所应用场景·案例分析 律所行业专家 行业解读
中企商学院
直播课 学员中心 学员升级 中企讲师
学习中心
电商运营学院 网站建设学院
企业通用
企业安全等保解决方案 企业全景展示解决方案 品牌数字化营销解决方案 品牌零售数字商业解决方案 开拓型外贸企业解决方案 成长型外贸企业解决方案 网站AI友好性解决方案
行业应用
一站式企业出海解决方案 智慧园区解决方案 零售行业OMO解决方案 B2B电商平台建设解决方案 数字化政务门户解决方案
行业解决方案
行业白皮书
企业概况
关于我们 企业文化 发展历程 数码庄园 法律隐私 FAQ
资质荣誉
企业资质 所获荣誉
新闻中心
热点资讯 行业活动
联系我们
联系我们 全国网点 工作机会
形状
  • 域名
  • 产品
  • 热点
  • 案例
  • 文章
  • 帮助中心
  • 课程
建站域名包含 .com、.cn、.net三款后缀
形状 搜索
建站推荐后缀
登录 注册 退出
    首页
  • 做网站
  • 做推广
  • 做电商
  • 成功案例 资讯热点
  • 服务支持
  • 应用与服务
  • 关于中企
  • 中企商学院
查看更多
核心必备
数字门户 内贸营销版
全球营销版 行业解决方案版
通用版 企业域名
企业邮箱
行业应用
外贸客户洞察 平台产品导入
数字名片
视觉设计
VR全景 视频制作
图片拍摄
网络安全
等保认证 SSL证书
查看更多
核心必备
全球SEO 百度首屏展位
Yandex推广 Google海外推广
解决方案
外贸推广解决方案
查看更多
核心必备
全网商城 移动商城
装修服务
电商产品拍摄
解决方案
零售行业OMO解决方案 政府采购电商平台解决方案
查看更多
查看更多
查看更多
帮助中心
数字门户产品服务保障 服务中心
设计师 信息化讲堂
解决方案
外贸数字营销解决方案 企业视频直播解决方案
企业安全等保解决方案 品牌数字化营销解决方案
品牌零售数字商业解决方案 智慧园区解决方案
B2B电商平台建设解决方案 数字化政务门户解决方案
开拓型外贸企业解决方案 成长型外贸企业解决方案
行业解决方案
实战应用
产品剖析 律所行业专家
行业解读
学习中心
电商运营学院 网站建设学院
查看更多
应用与服务
VR智能全景 个性化场景定制服务
网站安全服务 云定制
企业视频直播 Banner设计
产品主图设计 图片处理
查看更多
企业概况
关于我们 企业文化
发展历程 数码庄园
法律隐私
资质荣誉
企业资质 所获荣誉
新闻中心
新闻公告 媒体报道
社会公益 视频中心
行业资讯
联系我们
联系我们 工作机会
查看更多
查看更多
网站首页 网站建设 IT知识 IT知识教程 C/C++ 传递动态内存的深入理解

C/C++ 传递动态内存的深入理解

2021-05-20 21:21:13
当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。这些往往会使人受尽折磨。所以如果你想深入C/C++编程,你必须静下心来,好好苦一番。
现在我们将讨论C/C++里我认为哪一本书都没有完全说清楚,也是涉及概念细节最多,语言中最难的技术之一的动态内存的传递。并且在软件开发中很多专业人员并不能写出相关的合格的代码。
【引入】 看下面的例子,这是我们在编写库函数或者项目内的共同函数经常希望的。
复制代码 代码如下:
void MyFunc(char *pReturn, size_t size)
{
……
pReturn = (char *)malloc(sizeof(char) * num);
……
}

我们可以很明显地看出代码作者的意图,他想在函数调用处声明一个指针
char *pMyReturn=NULL;
然后调用MyFunc处理并返回一段长度为size的一段动态内存。
那么作者能达到预期的效果吗?
那么我可以告诉作者,他的程序在编译期很幸运地通过了,可是在运行期他的程序崩溃终止。
原因何在,是他触犯了系统不可侵犯的条款:错误地操作内存。
【内存操作及问题相关知识点】为了能彻底解决动态内存传递的问题,我们先回顾一下内存管理的知识要点。
(1)内存分配方式有三种:
●从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
●在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
●从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由我们决定,使用非常灵活。
(2)指针的操作流程
申请并初始化或设置为空:int *pInt=NULL;
开辟空间或者使其指向对象:pInt=new Int(3);或者int i=3;pint=&i;
用指针(更确切地说是操作内存,在使用之前加if(pint!=NULL)或者assert(pInt!=NULL)后再使用,以防内存申请失败的情况下使用指针):
if(p!=NULL) {use pint};
释放使用完的内存。free(pInt);
置指针为空pInt=NULL;(避免野指针的出现)
(3) 在函数的参数传递中,编译器总是要为函数的每个参数制作临时副本,如果参数为p的话,那么编译器会产生p的副本_p,使_p=p; 如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。
【问题分析】
根据上面的规则我们可以很容易分析例子中失败的原因。
复制代码 代码如下:
void MyFunc(char *pReturn, size_t size)
{
……
pReturn = (char *)malloc(sizeof(char) * num);
……
}
void main(void){
char *pMyReturn=NULL;
MyFunc(pMyReturn,10);
}

在MyFunc(char *pReturn, size_t size)中_pMyReturn真实地申请到了内存, _pMyReturn申请了新的内存,只是把_pMyReturn 所指的内存地址改变了,但是pMyReturn丝毫未变。所以函数MyFunc并不能输出任何东西。事实上,每执行一次MyFunc就会泄露一块内存,因 为没有用free释放内存。
【问题解决方案】
函数间传递动态数据我们可以有三种解决方法。
方法一。如果我们是用C++编程,我们可以很方便地利用引用这个技术。我也极力推荐你用引用,因为它会使你少犯一些错误。以下是一个例子。
复制代码 代码如下:
void MyFunc(char* &pReturn,size_t size){
pReturn=(char*)malloc(size);
memset(pReturn,0x00,size);
if(size>=13)
strcpy(pReturn,"Hello World!");
}
void main(){
char *pMyReturn=NULL;
MyFunc(pMyReturn,15);
if(pMyReturn!=NULL)
{
char *pTemp=pMyReturn;
while(*pTemp!=''\0'')
cout《*pTemp++;
pTemp=NULL;
strcpy(pMyReturn,"AAAAAAAA");
free(pMyReturn);
pMyReturn=NULL;
}
}

方法二。利用二级指针
复制代码 代码如下:
void MyFunc (char ** pReturn, size_t size)
{
* pReturn = (char *)malloc(size);
}
void main(void)
{
char * pMyReturn = NULL;
MyFunc (&pMyReturn, 100);// 注意参数是 & pMyReturn
if(pMyReturn!=NULL){
strcpy(pMyReturn, "hello");
cout《 pMyReturn 《 endl;
free(pMyReturn);
pMyReturn=NULL;
}}

为什么二级指针就可以了。原因通过函数传递规则可以很容易地分析出来。我们将& pMyReturn传递了进去,就是将双重指针的内容传递到了函数中。函数过程利用改变指针的内容,这样pMyReturn很明显指向了开辟的内存 .
方法三。 用函数返回值来传递动态内存
复制代码 代码如下:
char * MyFunc (void)
{
char *p =new char[20];
memset(p,0x00,sizeof(p));
return p;
}
void main(void)
{
char *str = NULL;
str = MyFunc();
if(str!=NULL)
{
strcpy(str,"Hello,baby");
cout《 str 《 endl;
free(str);
str=NULL;
}
}
请注意的是函数写成这样的话
char * MyFunc (void)
{
char *p =”Hello World”
return p;
}

的话,你是不能返回什么动态内存的,因为p指向的是字符串常量。内存在位于静态存储区
上分配,你无法改变。(你想要得到动态内存我们一定要看到malloc或者new)。
【结束语】
操作内存是C/C++一个难点,我们作为专业的软件开发人员。应该深入理解并能灵活地掌握指针和内存的操作。
delete的时候可能需要释放多个指针的内存
free和delete的区别是
对于对象来说
free的确释放了对象的内存,但是不调用对象的析构函数,所以如果在对象中使用new分配的内存就会泄露
delete不仅释放对象的内存,并且调用对象的析构函数
new和malloc虽然都是申请内存,但申请的位置不同,new的内存从free store分配,而malloc的内存从heap分配(详情请看ISO14882的内存管理部分),free store和heap很相似,都是动态内存,但是位置不同,这就是为什么new出来的内存不能通过free来释放的原因。不过微软编译器并没有很好的执行 标准,很有可能把free store和heap混淆了,因此,free有时也可以。
再补充一点:
delete时候不需要检查NULL

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。 如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章

详解C++ 动态内存分配与命名空间
1、C++中的动态内存分配通过new关键字进行动态内存申请C++中的动态内存申请时基于类型进行的delete关键用于内存释放C语言其实是不支持动态内存分配的,是
C++ 中继承与动态内存分配的详解
C++中继承与动态内存分配的详解继承是怎样与动态内存分配进行互动的呢?例如,如果基类使用动态内存分配,并重新定义赋值和复制构造函数,这将怎样影响派生类的实现呢?
C语言编程中分配内存空间的相关函数
C语言malloc()函数:动态分配内存空间头文件:#includemalloc()函数用来动态地分配内存空间(如果你不了解动态内存分配,请查看:C语言动态内存
一文搞懂C++ 动态内存
了解动态内存在C++中是如何工作的是成为一名合格的C++程序员必不可少的。C++程序中的内存分为两个部分:栈:在函数内部声明的所有变量都将占用栈内存。堆:这是程
c#基础系列之ref和out的深入理解
扩展阅读c#基础系列1---深入理解值类型和引用类型c#基础系列2---深入理解String引言在上篇文章深入理解值类型和引用类型的时候,有的小伙伴就推荐说一说

最新文章

载入进度条 效果
邮件发送简单例子-html文件
详解关于html,css,js三者的加载顺序问题
限制复选框的最大可选数
随鼠标上下滚动的jquery代码

hot 热门文章

python模拟登陆Tom邮箱示例分享
苹果11抖音怎么投屏? iphone将投影投屏到电视的技巧
蚂蚁森林节气签怎么领
华为mate30怎么更新系统?华为mate30更新手机系统教程
小米电视怎么下载斗鱼

猜你喜欢

JavaScript 命名空间 使用介绍
javascript ���名规则 变量命名规则
javascript 秒表计时器实现代码
Javascript 面向对象之重载
JavaScript 面向对象之命名空间
以上产品还未完全满足我的所有需求,在下方提交我的专属需求
我的专属需求:
*手机号:
*验证码:
img
咨询报价
现在咨询

Copyright © 1999-2026 中企动力科技股份有限公司(300.cn)All Rights Reserved

京公网安备11030102010293号 京ICP证010249-2

代理域名注册服务机构:中网瑞吉思(天津)科技有限公司 北京新网数码信息技术有限公司

域名注册服务机构许可证编号:京D3-20220007

中企动力域名投诉处理:400-660-5555-9 service4006@300.cn

中国互联网络信息中心(受理范围:“.CN”和“.中国”域名)投诉处理 010-58813000  service@cnnic.cn

立即联系我

立即提交
  • 7 x 24
    全国售后支持
  • 100 倍
    故障时长赔付
  • 27 年
    27年行业服务经验
  • 70 家
    全国售后支持
  • 1600+ 名
    超千人的设计、研发团队
  • 150 万
    服务企业客户150万家
联系我们| 意见反馈| 全国网点| 站点地图| 行业站| 邮箱登录| English| 中企集团官网
Copyright © 1999-2026 中企动力科技股份有限公司(300.cn)版权所有 京公网安备11030102010293号 京ICP证010249-2
代理域名注册服务机构:中网瑞吉思(天津)科技有限公司 北京新网数码信息技术有限公司
域名注册服务机构许可证编号:京D3-20220007
中企动力域名投诉处理:400-660-5555-9 service4006@300.cn
中国互联网络信息中心(受理范围:“.CN”和“.中国”域名)投诉处理 010-58813000  service@cnnic.cn
售后服务:400-660-5555-1
img

在线咨询

建站在线咨询

img

获取方案

获取建站报价/方案

我们联系您img

img

微信咨询

扫一扫添加
动力姐姐微信

img
img

TOP

我们尽快联系您