设为首页 加入收藏

TOP

关于C语言的内存分配
2013-04-10 11:21:06 来源: 作者: 【 】 浏览:531
Tags:关于 语言 内存 分配

  一转眼,工作也半年了,工作也如愿的成了一名C程序猿,驿站给了我很多帮助,想想自己也可以算是驿站的“老人”了,可是自己技术不精,学的又太浅,一直也不能写点啥有意义的帖子。最近工作时候,由于我写的代码内存的问题,导致设备死机查了很久,后来又好好学了学关于内存的分配相关的知识,小小的写点心得,因为技术有限,总结的不好,希望大家多多包函并给出补充。

  首先说下内存分配的方式吧,上次一位大牛在公司发邮件,告诉我们内核栈区只有4M,要求我们写代码的时候不用结构体数组,比如

  struct  Abc

  {

  \\.....

  }

  这样一个结构体,在函数中不让我们写

  Abc  abc[MAX];

  应该写成

  Abc* abc;

  abc = (Abc *)malloc( MAX*(sizeof( struct Abc)));

  当时我很不理解,这样大小不是一样的吗?后来查了相关资料,发现自己原来学习不求甚解,真害了自己。书上清清楚楚写着,动态分配内存是从堆中分配,而局部变量是从栈上创建,当时看的时候哪里管那么多,感觉都一样,原来差别很大啊。当然这东西很基础,我觉着也许还有些初学者会忽视堆、栈相关的内容吧,其实这挺重要的,我来说说它们的区别吧。内存区应该分为三块吧

  1、静态存储区域  这块内存是在程序编译就分配好的,在整个程序运行期间都存在,主要是用来放一些全局变量呀,static变量还有一些常量的

  2、栈区  我们老工程师说的4M的内核栈就是栈区,这块主要是存放局部变量的,函数执行完后存储单元被自动释放。栈的优点是效率较高,缺点就是空间相对较有限。

  3、堆区  我们动态分配内存的时候就是从这块区域来申请的,比如malloc和free,new和delete,这块区域相对较大,而且什么时候用什么时候释放我们说了算,很灵活,但是忘记释放会很麻烦。。。

  说说我上次犯过的一个错吧。是一个字符串处理的函数,有一个全局字符串指针data,我写的函数大体是

  char mstr[MAX]={0};

  dstr = data;\\dstr也是一个全局指针

  int i = 0;

  while(*dstr != '\0')

  {

  if((*dstr=='X')&&(*(dstr+1)=='X'))

  {

  dstr+=2;

  continue;

  }

  mstr[i++] = *dstr++;

  }

  data=mstr ;

  data主要是在这里处理一下,别处还要用,结果我再用的时候总是没有东西,其实挺简单的,当时就没看出来,这mstr是在这个函数里面的,函数结束了,也就没有了。。。当然,这是个破问题,不值得一提,还是说下比较容易犯的问题吧

  比较低级但也比较容易犯的,内存没有分配成功就用了。比如我前面写的abc = (Abc *)malloc( MAX*(sizeof( struct Abc)));应该加个保护if(NULL == abc)就返回类似的,就可以避免内存未分配成功就使用的问题了。当然,分配成功了,就不要忘记释放,否则会造成内存泄露,这样,每当你的函数掉用一次,就浪费一段内存区,到时候突然内存不足了,才可能发现。。。这个一定要记得牢牢的。释放了不算完事,要记着给你的指针赋值NULL避免产生野指针。比如free(p);p=NULL;

  其实说到这里差不多该说完了,但是说起指针了,不能不说下它和数组之间的一些事了。

  这里很多是我从网上查的,加上自己的理解。首先在一个函数中,如果你写char a[]="hello";那么这里的hello这个字符串为数组a的内容,也就是存在栈区的,你可以自己改,比如a[0]='y';这样是没有问题的,但是char* p="hello";就不一样了,p是在栈里的指针,但指向的内容却是静态区的字符串常量hello,不可以随便更改,可能说的有点绕,比如函数结束了,指针p被销毁了,但是字符串hello却没有被销毁。这样也会有一个有意思的事,比如说

  char* getString()

  {

  char a[]="bbb";

  return a;

  }

  你再p=getString();得到p中内容将会为未知内容,因为这里bbb只是数组a的内容,getString()结束后,a销毁,其内容bbb也会销毁,但是如果你写

  char* getString()

  {

  char* pst = "bbb";

  return pst;

  }

  p=getString();p就是bbb了,因为bbb是静态区的,哈哈。

  以上也就是我近日所理解的,总结的估计也不是很全,大家有啥跟帖补充一下吧,希望能对大家有用。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C语言编译全过程剖析 下一篇C语言中结构体小技巧

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: