C++与C#对比学习:内存管理

来源:互联网 发布:淘宝尺寸表怎么做 编辑:程序博客网 时间:2024/05/20 01:35

       我们知道计算机最重要的资源就是CPU和内存了.CPU的话我们貌似不能直接去操作,都是操作系统去管.而内存的话分为内核区和用户区.内核区是由操作系统管理,我们只能通过一些API去间接操作.而用户区就可以让应用程序去使用了.我们编程大部分时候就是在用户内存区中折腾来折腾去.

     C++内存分区

C++的内存一般分为栈(stack),堆(heap),自由存取区,全局/静态存储区,常量存储区,代码存储区.

栈(stack)

这是由系统自动去分配和管理,不用我们去操心.貌似大小就几M吧.有时我们也叫它堆栈.很容易和堆搞混了,还是看着英文爽点.另外这里的heap和数据结构中的堆不同,heap实际数据结构是指针链表.stack到就是数据结构中的栈.

堆(heap)

我们平时说的直接操作内存用的最多的就这个地方了,出问题出的最多的也就是这里.一般是用new去申请一块内存,用完了再delete掉.我们经常听到的啥内存泄露就是你new了一块内存后忘记delete掉了,或者delete时没有采取正确的方式,没能成功delete.

自由存储区

由malloc申请的存储区,用free来释放掉,这是兼容C的.在C++中用new时还会调用类的构造函数,而用malloc时只是给你分配内存,不会调用构造函数.反正在C++中基本上用new和delete就可以了,不用malloc也行的.另外有些人把自由存储区也划分到堆这一组.

全局/静态存储区

我们知道C++作为面向对象,所以一眼望过去都是一个个的类,啥变量,函数都是在类里面.但毕竟它不是纯面向对象.还有些特性是违反类的封装的,比如全局函数和全局变量.函数是存储在代码区.全局变量就存储在全局存储区.不过既然都说了是面向对象自然还是尽量按规矩办事好点,尽量别用全局变量.我们用全局变量时一般是因为某些变量不是属于某一个类的或某一个类的实例.如果是后一种情况我们可以用静态变量来替代.在类中用statics声明一个静态变量.静态变量直接用类名做前缀去访问,不能通过一个实例化的类去访问.它是保存在静态存储区.

常量存储区

像我们用const声明的变量就是常量.注意在C中有点不一样,const声明的变量可不叫常量,只有用define定义的才叫常量,而且这样的常量由于是在预编译阶段替换掉了,所以不用在内存中给常量分配内存了.另外除了用const显式指明是常量,还有种特殊情况隐式的是常量.char * pChar = "i am const"; //这个字符串就是一个常量,然后指针pChar指向它.

注意如果是这样string str = "i am string"; //这个双引号中的就不是常量了.它只是一般的变量值,存储在stack中.char*这是兼容C中的字符串,在C++可以不用它,用string好了.当然有时调用API或者和C交互还是要用到char*,这时可以把string ,char*互相转换下.

代码区

代码和函数就都保存在这个区.函数名相当于是个隐式的指针,我们调用某个函数时是使用函数名,函数名就指向代码区中具体的函数代码.

 

 另外一种划分法是分为:文本段(.text), 数据段(.data), stack,heap四种.

其中文本段是只读的,所以源代码,函数都放这.另外常量也放在这里.

数据段就是保存全局变量或静态变量

stack和heap跟上面说的就一样了.

C#内存分区

    由于直接操作内存会经常出问题,所以C#干脆连指针都不让你用,内存也不让你直接操作.CLR(common language runtime)有点像java的JVM,它给你去管理内存.

所以C#的内存分区没那么复杂,直接一个stack,和heap.stack跟C++差不多一样,还是系统去管.heap就是所谓的托管堆,由CLR替我们管理.当然heap里面可能还会分些啥区,但我们就不用去管那么多了,反正人家CLR给我们代劳了啊.C#中有值类型和引用类型的概念.所有基本类型加上struct都是值类型,是保存在stack中.而且string和数组还有自己定义的class都是分两部分保存,具体内容保存在heap中,但stack中保存有它们在heap中的内存地址(32位系统中就4字节,64位系统就8字节),觉得这其实非常像个指针了 .

 

C++直接操作内存与C#托管内存的优劣

很多人都讨论过这个问题,反正各执一词,各有各的道理.C++直接操作内存效率高,C#和Java中间隔了一层效率肯定差远了.但C#,java中不会再有那么多因直接操作内存而带来的问题.其实我们可以举个简单的比喻.就说玩QQ拖拉机或斗地主吧.你牌好时可以自己玩,牌差时不想玩就来个托管,让机器给你代劳.

如果你打牌技术非常厉害你自己打肯定比机器托管厉害,如果你不太会打牌还不如机器托管打的好.

用C++直接玩内存就相当于你自己打牌,而用C#,Java中的托管内存就相当于托管让机器给你玩牌.所以如果你技术非常厉害就用C++占优势点,不然的话用C#,java占优势点.

当然其实说到底语言只是一个工具,我们的目的是编写个有用的系统出来.所以如果一个系统本身的商业逻辑就非常的复杂的,比如大型web网站,你还要再纠缠在一些复杂的语法细节上就更复杂了 .所以用C#,java这样的开发效率更高.另外一个就是类库越多对我们来说也越好,很多事别人帮你做好了,你直接拿来用就好.而且很多类库都是些牛人写的,比你自己写的强多了.

 

原创粉丝点击