[转载]对于GetBuffer() 与 ReleaseBuffer() 的一些分析
先 转载一段别人的文章
CString类的这几个函数, 一直在用, 但总感觉理解的不够透彻, 不时还有用错的现象. 今天抽时间和Nico一起分析了一下, 算是拨开了云雾:
GetBuffer和ReleaseBuffer是一套需要配合使用的函数, 与GetBufferSetLength相比, 优点是如果分配的空间大于实际保存的字符串(0结尾), ReleaseBuffer会把多余申请的空间释放, 归还给系统; 但使用时需要注意以下问题: 如果要保存的字符串为abc(0结尾), 则GetBuffer参数应至少为3; 如果要保存的内容不是以0结尾, 比如是读取文件数据, 则GetBuffer参数如果大于文件长度时, ReleaseBuffer参数一定要为文件长度(如果GetBuffer参数为文件长度的话不存在问题, ReleaseBuffer参数可以为默认-1)!
CString csStr;
LPTSTR lpsz = csStr.GetBuffer(100);
lpsz[0] = 'a';
lpsz[1] = 'b';
lpsz[2] = '/0';
csStr.ReleaseBuffer();
int nLength = csStr.GetLength();
/* n的值为2 */
GetBufferSetLength相对比较容易理解, 它申请一个指定长度的空间, 即使里面最终保存的字符串长度小于申请的空间长度, 也不会将多余空间释放.
CString csStr;
LPTSTR lpsz = csStr.GetBufferSetLength(100);
lpsz[0] = 'a';
lpsz[1] = 'b';
lpsz[2] = '/0';
int nLength = csStr.GetLength();
/* n的值还是为100 */
对于红色部分,自己写代码时的确遇到过这样的问题:代码如下
CString temp;
ULONGLONG dwcount = Input_File.GetLength();
//UINT dwcount = (UINT)Input_File.GetLength();
Input_File.Read(temp.GetBuffer(dwcount),dwcount);
temp.ReleaseBuffer(dwcount);
若temp.ReleaseBuffer()不指定参数,执行这一步是会遇到错误,所以,类似的文件读取操作,releasebuffer的时候还是指定一个与getbuffer一样的参数为好
另:对于
(如果GetBuffer参数为文件长度的话不存在问题, ReleaseBuffer参数可以为默认-1)!
我设置temp.ReleaseBuffer(-1);此句执行的时候仍然出现错误,故还是指定文件长度为好
接下来看看其他的代码
CString str;
BROWSEINFO bi;
TCHAR name[MAX_PATH];
ZeroMemory(&bi,sizeof(BROWSEINFO));
bi.hwndOwner = GetSafeHwnd();
bi.pszDisplayName = name;
bi.lpszTitle = _T("选择文件夹");
bi.ulFlags = BIF_RETURNFSANCESTORS;
LPITEMIDLIST idl = SHBrowseForFolder(&bi);
if(idl == NULL)
return;
SHGetPathFromIDList(idl, str.GetBuffer(MAX_PATH));
////1
//CString aa = str.GetBuffer(MAX_PATH);
//CString bb = str; //运行此句之后,str内容变成乱码
//int a = aa.GetLength();
//int b = str.GetLength();
//LPTSTR cc = str.GetBuffer(MAX_PATH);
//LPTSTR dd = bb.GetBuffer(MAX_PATH);
//cc[1] = 'a';
//bb.ReleaseBuffer();
debug 参数如下图所示:
![]()
////2
CString aa = str.GetBuffer(MAX_PATH);
int a = aa.GetLength();
int b = str.GetLength(); //b无法获取str的长度
LPTSTR cc = str.GetBuffer(MAX_PATH);
cc[1] = 'a';
int e = str.GetLength(); //e无法正确获取str的长度,与3不同之处在于此处的str在蓝色字体getbuffer后未releasebuffer //妥善的做法是在两次str.getbuffer与str.GetLength()之间都都releasebuffer()下。
str.ReleaseBuffer();
int d = str.GetLength();
debug 参数如下所示:
![]()
////3
//CString aa = str.GetBuffer(MAX_PATH);
//str.ReleaseBuffer();
//CString bb = str; //bb的内容正确
//int a = aa.GetLength();
//int b = str.GetLength();
//LPTSTR cc = str.GetBuffer(MAX_PATH);
//LPTSTR dd = bb.GetBuffer(MAX_PATH);
//cc[1] = 'a';
//int d = str.GetLength(); //此处虽然可以正确获取str的值,但是在GetBuffer()后,最好还是在cc[1] = ‘a’ 后releasebuffer()一次。
//为何不再cc[1] = ‘a’前releasebuffer的原因: 虽然此处str仍然会变成”Ca/…..”,但是根据MSDN:在调用ReleaseBuffer之后,由GetBuffer返回的地址也许就无效了,因为其它的CString操作可能会导致CString缓冲区被重新分配。如果你没有改变此CString的长度,则缓冲区不会被重新分配。 妥当的做法是在cc[1]后releasebuffer
debug参数值如下所示:
![]()
////4
str.ReleaseBuffer(); // 对上面的SHGetPathFromIDList(idl, str.GetBuffer(MAX_PATH)); 进行的释放操作
CString aa = str.GetBuffer(MAX_PATH);
CString bb = str; // 执行完此句后,str的值不会变成乱码,和1类比
int f = str.GetLength(); //和1比,此处可以正确获取长度
str.ReleaseBuffer();
int a = aa.GetLength();
int b = str.GetLength();
CString ff = str.GetBuffer(MAX_PATH);
LPTSTR dd = bb.GetBuffer(MAX_PATH);
int d = str.GetLength();
![]()
对于一个CString 进行GetBuffer后,在进行该CString 的其他 CString 函数操作(尤其是 “=” “+” 等容易忽视的 CString 操作)前ReleaseBuffer(虽然从此处的几段代码执行情况来看,表面上在GetBuffer后在一次执行 CString操作不会导致错误,但是进行第二次CString 操作时就会产生错误。为了安全起见,getbuffer后需要在次执行CString的函数操作,先ReleaseBuffer()).
[转载]对于GetBuffer() 与 ReleaseBuffer() 的一些分析的更多相关文章
- 对于GetBuffer() 与 ReleaseBuffer() 的一些分析
先 转载一段别人的文章 CString类的这几个函数, 一直在用, 但总感觉理解的不够透彻, 不时还实用错的现象. 今天抽时间和Nico一起分析了一下, 算是拨开了云雾: GetBuffer和Rele ...
- GetBuffer与ReleaseBuffer的用法,CString剖析
转载: http://blog.pfan.cn/xman/43212.html GetBuffer()主要作用是将字符串的缓冲区长度锁定,releaseBuffer则是解除锁定,使得CString对象 ...
- 转载:AbstractQueuedSynchronizer的介绍和原理分析
简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...
- CString之GetBuffer与ReleaseBuffer
我们知道,CString是MFC中提供的方便字符串操作的一个类,非常好使,具有自动动态内存管理功能. GetBuffer()主要作用是将字符串的缓冲区长度锁定: ReleaseBuffer()则是解除 ...
- 转载 +function ($) { "use strict";}(window.jQuery);全面分析
转载 https://www.cnblogs.com/cndotabestdota/p/5664112.html +function ($) { "use strict";}(wi ...
- CString的GetBuffer和ReleaseBuffer
GetBuffer()主要作用是将字符串的缓冲区长度锁定,releaseBuffer则是解除锁定,使得CString对象在以后的代码中继续可以实现长度自适应增长的功能. CString ::GetBu ...
- [转载]Android 编译环境 build/envsetup.sh分析
2013-12-23 11:28:40 转载自: http://blog.csdn.net/evilcode/article/details/7005757 请到转载地址阅读原文, 转载以备查询.
- 【转载】linux环境下tcpdump源代码分析
linux环境下tcpdump源代码分析 原文时间 2013-10-11 13:13:02 CSDN博客 原文链接 http://blog.csdn.net/han_dawei/article/d ...
- 【转载】mysql 四种隔离级别分析
sql标准中,有四种隔离级别,各个离级别都有各自的规则,隔离级别越低,允许并发越大,消耗的资源越少,但是越不安全,下面就mysql数据库来分别介绍一下(每个存储引擎实施的隔离级别会有稍微的不同)mys ...
随机推荐
- 解决全局变量共享---C语言的extern关键字用法
在调试程序时,有一个参数需要在多个函数之间传递,因为是作为调试参数,不想将参数引入到函数中. 很自然的想到使用全局变量来表示这个公共参数,工程代码的结构如下: main.c test.c test.h ...
- button hot key 热键
<Button x:Name="ScanIDButton" Margin="11,0,0,0" IsEnabled="{Binding Elem ...
- MapKit的使用显示当前位置
1.添加MapKit.framework框架 ,在plist中添加字段,用于,获取用户当前位置设置 NSLocationAlwaysUsageDescription 2.代码 #import &quo ...
- python学习第三天
小结: 总体上,python是解释型语言,开源比较好,速度较慢,装逼神器,解释器较常用的是CPython,安装后python进入运行环境 exit()退出 第一个hello world : print ...
- flex_宽度补全
宽度40px,另一个的补全宽度: <!DOCTYPE html> <html lang="en"> <head> <meta charse ...
- Loadrunner的字符串函数
String Function包括 lr_advance_param 指向参数文件中参数的下一个值. lr_convert_string_encoding 将字符串转换为其他编码. lr_decryp ...
- PHP学习之常量
1.常量是一个简单值的标识符,该值在脚本中不能改变: 2.一个常量由英文字母,下划线,和数字组成,但数字不能作为首字母出现:(常量名中不需要加$修饰符) 3.常量在整个脚本中都可以使用: 4.设置PH ...
- HDU 4162 最小表示法
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4162 题意:给定一个只有0-7数字组成的串.现在要由原串构造出一个新串,新串的构造方法:相邻2个位置的数字 ...
- Codeforces Round #355 (Div. 2)-A
A. Vanya and Fence 题目连接:http://codeforces.com/contest/677/problem/A Vanya and his friends are walkin ...
- DOM--4 响应用户操作和事件(1)
简介 事件:事件并不是以"on"开头的.例如,onclick引用的是一个对象的属性,click才是事件. 事件侦听器:当指定的事件发生时会执行的函数或方法. 事件注册:为DOM元素 ...