<meta name="keywords" content="庄家克星时时彩,C语言" />
检查: 2723|回复: 4
打印 上一主题 下一主题

C语言以内存应用 [复制链接]

Hugo801122 (离线)
积分
886
帖子
192
跳转到指定楼层
楼主
揭晓于 2014-4-27 02:35:33 |只看该作者 |倒序浏览
要害词: C语言
这里我和年夜家一起探讨c语言的内存应用。
  曾经有同业写了一个把整数转换为字符串的函数:
char *itoa (int n)
{
  char retbuf[20];
  sprintf(retbuf, "%d", n);
  return retbuf;
}
  倘使我挪用该函数:char *str5 = itoa(5),str5会是甚么数值?
  效果是不愿定,唯一能一定的是效果不会是我们想要的 “5”。
    为何呢?由于retbuf界说在函数体中,它是部门变量,部门变量的内存空间位于客栈(stack)中,同时其作用规模也仅限于所在的函数中。此时当itoa()函数前往时,retbuf在客栈中的内容将被收受吸收,这块内存地址将能够被存放其他内容。以是把部门变量前往给函数挪用者是欠妥的,也是不应该的做法。
  这样我们该若那里置赏罚效果呢,别担忧,措施有许多且不止一个,下面就来叙述三种能处置赏罚赏罚这个效果的措施:
  1)、在itoa()函数外部用malloc() 为指针分配内存,同时将效果存放到外面,最后将retbuf前往给挪用者。由于此时retbuf分配于堆(heap)中,其对应空间不会随着函数前往而释放,以是能到达我们的目的。
  不外这里须要重视:挪用者在不须要retbuf的时间必须人工把它释放,挪用free函数来收受吸收空间,否则就组成内存走漏了。倘使该函数和挪用函数的都是统一小我所写则效果不年夜,否则将较量容易会疏漏此释放内存的行动。
  2)、在itoa()函数外部界说静态变量static char retbuf[20],这异常能保证函数前往后retbuf的空间不被收受吸收,这是由于静态变量着实不是存放在客栈中,而是存放在一个叫“.bss”段的地方,该地方的内容是不会因函数前往而被收受吸收的。
  这类措施虽然能处置赏罚赏罚效果,不外它也招致了函数酿成了一个弗成重入函数(即不克不及保证类似的输入一定有类似的输入)。同时, retbuf [] 中的内容会被函数的下一次挪用效果所取代,该措施不值得推荐。
  3)、应用指针参数,将函数界说为char *itoa(int n, char *retbuf),而且retbuf由函数挪用者要求和释放,这时间间辰itoa()只是将转换效果存放到retbuf。
  很显着这类措施比第一、二种措施强,首先防止了措施1对函数的影响,同时也回避了措施2对内存分配释放的影响,是业内一种较量通用盛行的做法。
  扩年夜剖析:
  假定就该效果自己而言,想必年夜家都可以迅速想到谜底,效果要害就在对memory这类敏感资源的准确和公正地应用,上去我们对内存做个质朴的剖析:


  1)、法式模范模范中分为不合的内存段,网罗:
  .heap - 堆,由法式模范模范显式分配和收回,假定不收回就是内存走漏。
  .bss - 未初始化全局/静态变量,在所有软件推行历程当中有用;
  .data - 已初始化全局/静态变量,在所有软件推行历程当中有用;
  .stack - 函数挪用栈,其中的内容在函数推行时代有用,并由编译器担负分配和收回;
  2)、自己治理的内存尽能够自己要求和释放。
  这现实上是一个内存分配和释放的基泉源基础则,例如说下面的第二种措施,由itoa()分配的内存,却由挪用者释放,就不是一个很是好的做法,它显着不如第三种,由挪用者自己要求和释放。此外该准绳尚有此外一层意思:若应用一个指针,最好先确保它曾经指向一个正当地址,否则就自己分配,否则即非法地址会见。许多法式模范模范的致命弱点都是会见一个没有指向正当内存区的指针,也就是野指针,也网罗空指针。


效果:内存分配 & sizeof
  假定应用sizeof来盘算一个指针变量,欲望取得这个指针变量所分配的内存块的年夜小,可以吗?


char *p = NULL;
int nMemSize = 0;

p = malloc(1024);
nMemSize = sizeof(p);


  谜底与剖析:


  效果是达不到你的请求的,sizeof只能告诉你指针变量自己占用的内存年夜小。指针所指向的内存,假定是malloc分配的,sizeof 是没法知道的。换言之,malloc分配的内存是没法向内存治理模块阻拦事后查询的,虽然你是可以自己编写代码来治理掩护。


  效果:栈内存应用


  下面的法式模范模范运转会有甚么效果?


char *GetString(void)
{
  char p[] = "hello world";
  return p;// 编译器将提出正告
}


void Test4(void)
{
  char *str = NULL;
  str = GetString();// str 的内容是残余
  cout<< str << endl;
}


  谜底与剖析:


  前往栈内存,内存能够被销毁也能够或许不被实时销毁,但可以一定的是出了作用域以后已被标志成可被系统应用,是以会前往杂乱无章弗成知内容。虽然,前往的指针的内容,应当是稳固的,特殊时间是有用的,好比,可以用来探测系统内存分配纪律等。


  效果:内存应用相关编程尺度


  假设想尽能够地防止内存应用上的效果,有甚么捷径吗?


  谜底与剖析:


  除非做一件从没有人做过的使命,否则都是有捷径可言的,谜底那就是站在祖先的肩膀上,当今各个年夜公司都有自己的编码尺度,这些尺度凝集了许多的履历履历,有较高的应用价值,推敲到这些尺度在网上撒播许多,这里我就不再枚举了,感兴趣的,推荐参考林锐的《高质量C/C++编程指南》。


,的家园!51嵌入式官方QQ群52497844,迎接喜欢者加入。
,繁复而不质朴!
云峰 (离线)
积分
86
帖子
5
沙发
揭晓于 2014-4-28 17:45:04 |只看该作者
是想叙述函数挪用历程么?
Hugo801122 (离线)
积分
886
帖子
192
板凳
揭晓于 2014-4-30 02:39:26 |只看该作者
云峰 揭晓于 2014-4-28 17:45
是想叙述函数挪用历程么?

不是,这里是将内存的应用,好比客栈和堆的差异。
,的家园!51嵌入式官方QQ群52497844,迎接喜欢者加入。
,繁复而不质朴!
spy007868 (离线)
积分
9941
帖子
1605
地板
揭晓于 2014-5-4 09:00:59 |只看该作者
复制上去!!!!!!!!!我自己好好学习!!!!!!!!!!!!!!

谢谢.jpg (8.65 KB, 下载次数: 98)

谢谢.jpg

云峰 (离线)
积分
86
帖子
5
地下室
揭晓于 2014-5-4 20:46:30 |只看该作者
Hugo801122 揭晓于 2014-4-30 02:39
不是,这里是将内存的应用,好比客栈和堆的差异。

但函数的挪用历程不就是客栈的应用历程么
您须要登录后才可以揭晓议论 登录 | 急速注册

关于我们  -  服务条目  -  应用指南  -  站点舆图  -  友谊链接  -  联系我们
庄家克星时时彩-时时彩qq群-时时彩平台推荐 © 版权所有   | 京公网安备110108881021702
回顶部
幸运五张-幸运五张规则-掌联幸运五张安卓版 捕鱼达人3-捕鱼达人3无限金币免费版 北京pk10-北京pk10新凤凰-凤凰pk10预测 安徽福彩网-安徽福彩快3网上购买 888棋牌游戏-盛大娱乐棋牌平台-棋牌电玩城送彩金 助赢时时彩-韩国时时彩助赢-韩国时时彩助赢计划 亿酷棋牌-象棋棋牌-棋牌游戏娱乐下载 北京pk10开奖-pk10赛车群-pk10开奖首选网上手游 qq捕鱼大亨-千炮捕鱼-qq游戏捕鱼大亨 时时彩后二-时时彩后二技巧-时时彩后二计划 开心棋牌-娱乐棋牌送救济金-四方棋牌送救济金 11选5软件-快赢11选5软件-11选5玩法 波克棋牌-现金牛牛棋牌-亲朋棋牌游戏手游 亲朋棋牌-舟山99棋牌-唐朝电玩城棋牌 天逸时时彩-时时彩开奖结果-时时彩全天计划稳赢版