zoukankan      html  css  js  c++  java
  • 对于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相对照较easy理解, 它申请一个指定长度的空间, 即使里面终于保存的字符串长度小于申请的空间长度, 也不会将多余空间释放.
    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 參数例如以下图所看到的:

    11

     

    ////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 參数例如以下所看到的:

    22

    ////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參数值例如以下所看到的:

    33

    ////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();            

    image

     

     

     

    对于一个CString 进行GetBuffer后,在进行该CString 的其它 CString 函数操作(尤其是 “=” “+” 等easy忽视的 CString 操作)前ReleaseBuffer(尽管从此处的几段代码运行情况来看,表面上在GetBuffer后在一次运行 CString操作不会导致错误,可是进行第二次CString 操作时就会产生错误。为了安全起见,getbuffer后须要在次运行CString的函数操作,先ReleaseBuffer()).

  • 相关阅读:
    【DUBBO】dubbo架构详解(转载)
    【数据库】sql连表查询
    第十三章 三种非对称加密算法总结
    第十二章 非对称加密算法-RSA
    第十一章 非对称加密算法--DH
    第十章 五种对称加密算法总结
    第九章 对称加密算法--IDEA
    第八章 对称加密算法--AES
    第七章 对称加密算法--DES
    第六章 三大消息摘要算法总结
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4352738.html
Copyright © 2011-2022 走看看