DELPHI之关于String的内存分配(引)
在函数、过程或者方法中定义一个字符串变量时,由于我们知道在函数、过程或者方法中定义的变量为局部变量,它的内存
是在栈中分配的,但是这里有个小细节我们要注意,对于一个局部的字符串变量,它的大小为4字节,这个在栈中分配的4字
节是不是就是字符串变量的全部呢?答案是否定的,它在栈中保存的只是这个字符变量的大小和字符变量的值在堆中的内存
地址!,这就是说,该字符变量的值并不在对应的栈中,而是在堆中!我们了解到在堆上分配的内存是要程序员来处理内存
释放的,而我们在使用String类型的变量时从来就没有处理过该变量占用的内存!这是什么原因呢?这里我们就要讲到
编译器的引用计数原理了,正是因为它为我们省去了很多麻烦(当然,在某些情况我们还是小心为上,下面会提出),引用
计数其实通俗的讲就是这块内存被几个变量引用,就为这块内存计上数(可能表述不正确,但为了好记好理解故此说),是
1个就是1,有2个就是2,以此类推。当一个字符串变量使用完后,编译器自动的将其引用计数减1,如果发现引用计数为0
时,这个字符变量所占用的内存空间就被释放了。需要注意的是,什么情况下会发生引用计数呢?如果定义一个字符串变量
并给其赋值,那么这个字符串变量引用计数为1,此时假若我们再定义一个字符串变量,并将第一个字符变量的值赋值给第
二个字符变量,此时将引发引用计数,变为2,注意,编辑器此时并没有给第二个字符变量复制一份第一个字符变量的值,
而只是将第一个字符变量值的地址指针给了它!也就是说,第一个和第二个字符的值都在同一个内存块中!。但是我们通过
访问数组元素的方式访问字符变量的时候或者修改上面其中一个字符变量时,这时会引发”写复制“,之后两个字符串变量开
始使用不同的内存占用。因为所有这些对程序员来说是不必费心处理的,它全部由编译器来自动完成,那么我们在什么情况
下要小心呢?这里就和DLL有关系了,我们知道在EXE程序调用DLL时,EXE和DLL之间都是各自使用自己的内存管理器,
麻烦就出在这,假如我们在EXE中调用DLL的一个输入函数时返回一个字符串,我们知道这个字符串的引用计数为1,EXE在
使用完这个字符串后将其引用计数减1,那就是0了,按照惯例,编译器对字符串所占用的内存进行清除释放,OK,一切顺利,
那么这时该轮到DLL处理了,前面说过EXE和DLL各有各的内存管理器,这时DLL是不知道EXE已将字符串内存释放掉了,并
且还要访问那个被释放了的字符串,字符串都不存在了,访问哪儿呢?于是程序就出问题了,很显然这是我们所不希望看到的,
所在在使用DLL时,为了避免这个问题发生,我们可以有多种解决方案
1、使用内存映射文件
2、DLL单元和EXE单元都引用ShareMem单元
3、不用String类型(注:动态数组、接口和变体类型也有引用计数机制),改用PChar类型
https://i.cnblogs.com/EditPosts.aspx?opt=1
DELPHI之关于String的内存分配(引)的更多相关文章
- delphi 精要-读书笔记(内存分配释放)
delphi 精要-读书笔记(内存分配释放) 1.内存分为三个区域:全局变量区,栈区,堆区 全局变量区:专门存放全局变量 栈区:分配在栈上的变量可被栈管理器自动释放 堆区:堆上的变量内存必须人 ...
- 深度解析对象的hashcode和equals的差异,以及String的内存分配方式
Q:Java对象的hashcode是怎么得到的 A:Java对象的hashcode是native方法,不是通过Java实现的.hashcode的值是根据对象的内存地址得到的一串数字. Q:如果两个对象 ...
- String的内存分配
1.String类是final类不能被继承 2.String str="abc"的内部工作 (1)先在栈中定 一个名为str的String类的引用变量 String str: (2 ...
- JAVA基础-栈与堆,static、final修饰符、内部类和Java内存分配
Java栈与堆 堆:顺序随意 栈:后进先出(Last-in/First-Out). Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new.newarray.anewarray和mu ...
- 标准C++类std::string的内存共享和Copy-On-Write...
标准C++类std::string的 内存共享和Copy-On-Write技术 陈皓 1. 概念 Scott Meyers在<More Effective C++>中举了个例子,不知你是否 ...
- 【转】标准C++类std::string的内存共享和Copy-On-Write技术
1. 概念 Scott Meyers在<More Effective C++>中举了个例子,不知你是否还记得?在你还在上学的时候,你的父母要你不要看电视,而去复习功 ...
- 标准C++类std::string的内存共享和Copy-On-Write技术
标准C++类std::string的 内存共享和Copy-On-Write技术 陈皓 1. 概念 Scott Meyers在<More Effective C++>中举了个例子,不知你是 ...
- java内存分配和String类型的深度解析
[尊重原创文章出自:http://my.oschina.net/xiaohui249/blog/170013] 摘要 从整体上介绍java内存的概念.构成以及分配机制,在此基础上深度解析java中的S ...
- 终于懂了:Delphi的函数名不是地址,取地址必须遵守Object Pascal的语法(Delphi和C的类比:指针、字符串、函数指针、内存分配等)good
这点是与C语言不一样的地方,以前我一直都没有明白这一点,所以总是不明白:函数地址再取地址算怎么回事? ------------------------------------------------- ...
随机推荐
- 使用lapack图书馆逆矩阵
阿土,直接在代码: #include <string> #include "lapacke.h" #include "lapack_aux.h" i ...
- SCM文章9类:外部中断示例程序
JP3遇见P0口,JP5遇见P3口,P1接受该发光二极管,什么时候P1所有的都是高时,,全亮度发光二极管.因为外部中断0和1用同样的方法.这里只是外部中断0计划. #include<reg51. ...
- vector, list, deque的选用(vector适用少量对象,list适用大量对象),以及效率问题
如何选择这三个容器中哪一个,应根据你的需要而定,一般应遵循下面的原则: 1.如果你需要高效的随机存取,而不在乎插入和删除的效率,使用vector 2.如果你需要大量的插入和删除,而不关心随机存取( ...
- Android Studio入门(安装-->开发调试)
写在前面的话:本文来源:http://blog.csdn.net/yanbober/article/details/45306483 目标:Android Studio新手–>下载安装配置–&g ...
- 定制Octopress
在 github pages 上搭建好 octopress 博客之后,博客的基本功能就能使用了.如果想自己定制也是没问题的,octopress 有较详尽的官方文档,原则上有问题求助官方即可:octop ...
- 编程算法 - 二叉搜索树(binary search tree) 代码(C)
二叉搜索树(binary search tree) 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 二叉搜索树(binary search tree)能 ...
- 推断(inference)、贝叶斯规则(Bayes's rule)与导出分布(derived distribution)
1. 建模 对原始信号 X 进行观测,观测可以抽象为(离散:PY|X(y|x), 连续:fY|X(y|x)),物理世界噪声的存在,将导致观测到的 X 出现一定的噪声,记为 Y: X⇒fY|X(y|x) ...
- sklearn 下距离的度量 —— sklearn.metrics
1. pairwise from sklearm.metrics.pairwise import pairwise_distance 计算一个样本集内部样本之间的距离: D = np.array([n ...
- 【STL】关联容器 — hashtable
C++ 11哈希表已被列入标准列.hashtable这是hash_set.hash_map.hash_multiset.hash_multimap的底层机制.即这四种容器中都包括一个hashtable ...
- C++ Primer 学习笔记_104_特殊工具与技术 --嵌套类
特殊工具与技术 --嵌套类 能够在还有一个类内部(与后面所讲述的局部类不同,嵌套类是在类内部)定义一个类,这种类是嵌套类,也称为嵌套类型.嵌套类最经常使用于定义运行类. 嵌套类是独立的类,基本上与它们 ...