先 转载一段别人的文章

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() 的一些分析的更多相关文章

  1. 对于GetBuffer() 与 ReleaseBuffer() 的一些分析

    先 转载一段别人的文章 CString类的这几个函数, 一直在用, 但总感觉理解的不够透彻, 不时还实用错的现象. 今天抽时间和Nico一起分析了一下, 算是拨开了云雾: GetBuffer和Rele ...

  2. GetBuffer与ReleaseBuffer的用法,CString剖析

    转载: http://blog.pfan.cn/xman/43212.html GetBuffer()主要作用是将字符串的缓冲区长度锁定,releaseBuffer则是解除锁定,使得CString对象 ...

  3. 转载:AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  4. CString之GetBuffer与ReleaseBuffer

    我们知道,CString是MFC中提供的方便字符串操作的一个类,非常好使,具有自动动态内存管理功能. GetBuffer()主要作用是将字符串的缓冲区长度锁定: ReleaseBuffer()则是解除 ...

  5. 转载 +function ($) { "use strict";}(window.jQuery);全面分析

    转载 https://www.cnblogs.com/cndotabestdota/p/5664112.html +function ($) { "use strict";}(wi ...

  6. CString的GetBuffer和ReleaseBuffer

    GetBuffer()主要作用是将字符串的缓冲区长度锁定,releaseBuffer则是解除锁定,使得CString对象在以后的代码中继续可以实现长度自适应增长的功能. CString ::GetBu ...

  7. [转载]Android 编译环境 build/envsetup.sh分析

    2013-12-23 11:28:40 转载自: http://blog.csdn.net/evilcode/article/details/7005757 请到转载地址阅读原文, 转载以备查询.

  8. 【转载】linux环境下tcpdump源代码分析

    linux环境下tcpdump源代码分析 原文时间 2013-10-11 13:13:02  CSDN博客 原文链接  http://blog.csdn.net/han_dawei/article/d ...

  9. 【转载】mysql 四种隔离级别分析

    sql标准中,有四种隔离级别,各个离级别都有各自的规则,隔离级别越低,允许并发越大,消耗的资源越少,但是越不安全,下面就mysql数据库来分别介绍一下(每个存储引擎实施的隔离级别会有稍微的不同)mys ...

随机推荐

  1. .net Session 详解

    (一) 描述当用户在 Web 应用程序中导航 ASP.NET 页时,ASP.NET 会话状态使您能够存储和检索用户的值.HTTP 是一种无状态协议.这意味着 Web 服务器会将针对页面的每个 HTTP ...

  2. [转载]void及void*的深度剖析

    void的含义 void即"无类型",void *则为"无类型指针",可以指向任何数据类型. void指针使用规范 ①void指针可以指向任意类型的数据,亦即可 ...

  3. poj 2063 Investmen 完全背包

    这个题的想法不难,两个点: 1 是完全背包 2 是考虑/1000,降低复杂度   但是提交的时候反复的wa,最后找问题原来是dp开小了,可是dp本来开1005,后来开到100030过了.哎,如果没有时 ...

  4. torch7安装

    按照官网进行安装即可;(http://torch.ch/docs/getting-started.html#_) # in a terminal, run the commands WITHOUT s ...

  5. 17996 Daily Cool Run (dp)

    时间限制:1000MS  内存限制:65535K 提交次数:0 通过次数:0 题型: 编程题   语言: 不限定 Description Daily Cool Run is a popular gam ...

  6. Codeforces Round #345 (Div. 2)

    DFS A - Joysticks 嫌麻烦直接DFS暴搜吧,有坑点是当前电量<=1就不能再掉电,直接结束. #include <bits/stdc++.h> typedef long ...

  7. Git分支操作

    1.创建分支 git branch <分支名> 2.切换分支 git checkout <分支名> 该语句和上一个语句可以和起来用一个语句表示: git checkout -b ...

  8. three.js 场景入门

    <!DOCTYPE html> <html> <head> <title>Example 01.02 - First Scene</title&g ...

  9. EF框架step by step(9)—Code First Fluent API

    在上一篇中,讲述了用数据特性的方式来标识实体与数据表之间的映射关系,在Code First方法中,还可以通过Fluent API的方式来处理实体与数据表之间的映射关系. 要使用Fluent API必须 ...

  10. WPF中ControlTemplate和DataTemplate的区别

    下面代码很好的解释了它们之间的区别: <Window x:Class="WPFTestMe.Window12" xmlns="http://schemas.micr ...