• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 319, comments - 22, trackbacks - 0, articles - 11
              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

                 摘要: 詳解QT 信號機(jī)制 (上篇)2011-07-05 18:32 佚名 互聯(lián)網(wǎng) 我要評論(1) 字號:T | T信號不是Unix中進(jìn)程間通信的信號。這里的信號更多地與圖形界面的輸入輸出聯(lián)系在一起(當(dāng)然也可以是不可見的操作)。先來看內(nèi)容。AD:QT 信號機(jī)制 是本文要介紹的內(nèi)容,Qt用預(yù)編譯器和宏來保證強(qiáng)大的跨平臺能力,信號機(jī)制則是其中最精妙之處。本文分...  閱讀全文

            posted @ 2011-07-14 07:14 RTY 閱讀(896) | 評論 (0)編輯 收藏

            作者: Peter Wang (Intel) (28 篇文章) 日期: 九月 17, 2010 在 2:14 下午

            最近Intel新發(fā)布的產(chǎn)品Intel® Parallel Studio 2011包含四個(gè)組件:Intel® Parallel Composer 2011, Intel® Parallel Inspector 2011,Intel® Parallel Amplifier 和Intel® Parallel Advisor。

            我們知道Intel® Parallel Inspector 2011 可以對程序進(jìn)行動態(tài)檢查,包含內(nèi)存檢查和線程檢查。

            現(xiàn)在Intel® Parallel Studio 2011不用執(zhí)行程序,也可以發(fā)現(xiàn)原代碼的錯(cuò)誤。這個(gè)功能(Static Security Analysis - SSA) 給我們帶來的好處是:

            1. 只檢查原代碼,不檢查程序。在最終程序生成前,發(fā)現(xiàn)問題。節(jié)約了大量的調(diào)試時(shí)間
            2. 檢查所有的代碼,不管路徑有沒有被執(zhí)行到
            3. 還檢查“死代碼”
            4. 只專注于內(nèi)存訪問,不檢查線程訪問
            5. 無需Test Case (User Input)

            SSA功能由二部分來實(shí)現(xiàn):

            1. Intel® Parallel Composer 2011 實(shí)現(xiàn)靜態(tài)掃描,生成結(jié)果
            2. Intel® Parallel Inspector 2011 打開結(jié)果文件,進(jìn)行分析

            Intel® Parallel Composer 2011 上的關(guān)鍵步驟:

            1. 選擇Intel C++編譯器

            2. 改變編譯器的選項(xiàng)

            3. 重新Rebuild, 生成結(jié)果

            Intel® Parallel Inspector 2011上的關(guān)鍵步驟:

            1. 打開結(jié)果文件,檢查某個(gè)錯(cuò)誤

            2. 對照原代碼,發(fā)現(xiàn)問題

            3. 利用“幫助”,解釋問題

            分類: Blog Challenge, 并行計(jì)算, 英特爾® 軟件網(wǎng)絡(luò) 2.0
            標(biāo)簽:
            如需了解英特爾軟件產(chǎn)品相關(guān)的性能和優(yōu)化選項(xiàng),請參閱優(yōu)化注意事項(xiàng).

            posted @ 2011-07-13 21:39 RTY 閱讀(532) | 評論 (0)編輯 收藏

             如題,鏈接如下:

            http://developer.qt.nokia.com/elearning

             

            posted @ 2011-07-13 07:18 RTY 閱讀(318) | 評論 (0)編輯 收藏

                 摘要: QML是什么?QML 是一中聲明式語言,用來描述應(yīng)用程序接口的――是什么樣,有怎樣的行為。在QML中,一個(gè)用戶接口被指定為帶有屬性的對象是。這個(gè)介紹主要面向只有很少或者沒有編碼經(jīng)驗(yàn)的人。在QML中,JavaScript作為一種腳本語言被使用。因此在深入學(xué)習(xí)QML之前,也許你會想要去學(xué)一些關(guān)于JavaScript的知識(JavaScript: The Definitive G...  閱讀全文

            posted @ 2011-07-06 22:03 RTY 閱讀(1461) | 評論 (0)編輯 收藏

            styleSheet : QString

            This property holds the widget's style sheet.

            The style sheet contains a textual description of customizations to the widget's style, as described in the Qt Style Sheets document.

            Since Qt 4.5, Qt style sheets fully supports Mac OS X.

            Warning: Qt style sheets are currently not supported for custom QStyle subclasses. We plan to address this in some future release.

            This property was introduced in Qt 4.2.

            Access functions:

            QStringstyleSheet () const
            voidsetStyleSheet ( const QString & styleSheet )


            一定要注意速度,平凡的調(diào)用,一般會消耗0.25倍的CPU資源

            posted @ 2011-07-04 20:47 RTY 閱讀(3201) | 評論 (0)編輯 收藏

              1 #!/usr/bin/env python
              2 # -*- coding: utf-8 -*-
              3 
              4 
              5 # Fast copy for Winodws or Linux
              6 # Copy file to
              7 
              8 import os
              9 import sys
             10 import re
             11 from optparse import OptionParser
             12 
             13 
             14 def CallFastCmd(src, dest):
             15      cmd = "XCOPY " + src +" " + dest
             16      print u"命令行"+ cmd
             17      os.system(cmd)
             18 
             19 def SplitStr(src, split):
             20      return src.split(split)
             21 
             22 
             23 
             24 def IsCanCopy(path, include, exclude):
             25     IsCan = False
             26     split = "|"
             27     if include is None:
             28         if exclude is None:
             29             IsCan = True
             30         else:
             31             for excStr in SplitStr(exclude, split):
             32                if (excStr not in path):
             33                    IsCan = True
             34     else:
             35         for incStr in SplitStr(include, split):
             36 
             37              if exclude is not None :
             38                  for excStr in SplitStr(exclude, split):
             39                      if (excStr not in path) and (incStr in path):
             40                          IsCan = True
             41              elif incStr in path:
             42                  IsCan = True
             43 
             44 
             45 
             46     #返回值
             47     return IsCan
             48 
             49 
             50 
             51 def CopyToSubDir(src, des, include, exclude, regEnable):
             52     for root,dirs,files in os.walk(des):
             53         for dirPath in dirs:
             54             subPath = os.path.join(root,dirPath) # 路徑
             55             if not regEnable:
             56                if IsCanCopy(subPath, include, exclude):
             57                    CallFastCmd(src, subPath)
             58             else#使用正則表達(dá)式
             59                 incReg = include
             60                 excReg = exclude
             61 
             62                 incMatch = incReg.match(incReg, subPath)
             63                 if incMatch is not None:
             64                     excMatch = excReg.match(excReg, subPath)
             65                     if excMatch is None:
             66                         CallFastCmd(src, subPath)
             67 
             68 
             69 
             70 
             71 
             72 def Copy(src, des, include, exclude , regEnable):
             73     if not os.path.exists(des):
             74         CallFastCmd(src, des)
             75     else:
             76         CopyToSubDir(src, des, include, exclude, regEnable)
             77 
             78 
             79 
             80 def ParseCmd():
             81     parser = OptionParser()
             82     parser.add_option("-s""--src", action="store", dest="src", help="input the Dir or file")
             83     parser.add_option("-d""--des", action="store", dest="des", help="input the Dir or file")
             84     parser.add_option("-i""--include",action="store", dest="include", help="input the include string")
             85     parser.add_option("-e""--exclude",action="store", dest="exclude", help="input the exclude string")
             86     parser.add_option("-r""--regEnable",action="store_true", dest="regEnable", default=False, help="input the exclude string")
             87 
             88 
             89     (options, args) = parser.parse_args()
             90     if options.src is None:
             91         parser.error("The source is none")
             92     if options.des is None:
             93         parser.error("The dest is none")
             94 
             95     Copy(options.src, options.des, options.include, options.exclude, options.regEnable)
             96 
             97 if __name__ == "__main__":
             98     ParseCmd()
             99 
            100 

            posted @ 2011-06-21 00:47 RTY 閱讀(477) | 評論 (0)編輯 收藏

            Advanced PDF Password Recovery(PDF 文件解密的方案) V5.00 漢化綠色特別版


            Advanced PDF Password Recovery(PDF 文件解密的方案) V5.00 漢化綠色特別版
            Advanced PDF Password Recovery可以破解Adobe Acrobat PDF文件的“所有者密碼”。未破解“所有者密碼”的PDF文件是不能被編輯和打印的。該程序也可以破解用FileOpen插件加密的文件。破解可以立即 完成。破解后的文件可以用各種PDF瀏覽器(例如Adobe Acrobat Reader)閱讀而無任何限制。
            支持命令行格式
            支持PDF文件限制直接解除
            支持PDF文件密碼的暴力破解
            支持幾種解密方式
            支持PDF最新的版本

            sn:APDFPR-P-R844-JCEN-BMSK



            posted @ 2011-06-19 21:05 RTY 閱讀(2028) | 評論 (0)編輯 收藏

            一、針對Microsoft
            #include   <stdlib.h>


            (1)第一種方式
            system( "PAUSE ");
            --------------------
            (2)第二種方式
            getchar();
            ---------------------
            (3)第三種方式
            Sleep();



            二、針對Linux
            (1)第一種方式
            getchar();

            posted @ 2011-06-18 22:04 RTY 閱讀(5430) | 評論 (0)編輯 收藏

            概述

              size_t 類型定義在cstddef頭文件中,該文件是C標(biāo)準(zhǔn)庫的頭文件stddef.h的C++版。它是一個(gè)與機(jī)器相關(guān)的unsigned類型,其大小足以保證存儲內(nèi)存中對象的大小。   例如bitset的size操作返回bitset對象中二進(jìn)制位中的個(gè)數(shù),返回值類型是size_t。   例如在用下標(biāo)訪問元素時(shí),vector使用vector::size_type作為下標(biāo)類型,而數(shù)組下標(biāo)的正確類型則是size_t。

            來源

              size_t是標(biāo)準(zhǔn)C庫中定義的,應(yīng)為unsigned int。   數(shù)據(jù)類型"socklen_t"和int應(yīng)該具有相同的長度。否則就會破壞 BSD套接字層的填充.POSIX開始的時(shí)候用的是size_t, Linus Torvalds(他希望有更多的人,但顯然不是很多) 努力向他們解釋使用size_t是完全錯(cuò)誤的,因?yàn)樵?4位結(jié)構(gòu)中 size_t和int的長度是不一樣的,而這個(gè)參數(shù)(也就是accept函數(shù)的第三參數(shù))的長度必 須和int一致,因?yàn)檫@是BSD套接字接口標(biāo)準(zhǔn).最終POSIX的那幫家伙找到了解決的辦法,那就是創(chuàng)造了一個(gè)新的類 型"socklen_t".Linux Torvalds說這是由于他們發(fā)現(xiàn)了自己的錯(cuò)誤但又不好意思向大家伙兒承認(rèn),所以另外創(chuàng)造了一個(gè)新的數(shù)據(jù)類型 。   在C++中,設(shè)計(jì) size_t 就是為了適應(yīng)多個(gè)平臺的 。size_t的引入增強(qiáng)了程序在不同平臺上的可移植性。size_t是針對系統(tǒng)定制的一種數(shù)據(jù)類型,一般是整形,因?yàn)镃/C++標(biāo)準(zhǔn)只定義一最低的位 數(shù), 而不是必需的固定位數(shù)。而且在內(nèi)存里,對數(shù)的高位對齊存儲還是低位對齊存儲各系統(tǒng)都不一樣。為了提高代碼的可移植性,就有必要定議這樣的數(shù)據(jù)類型。一般這 種類型都會定義到它具體占幾位內(nèi)存等。當(dāng)然,有些是編譯器或系統(tǒng)已經(jīng)給定義好的。經(jīng)測試發(fā)現(xiàn),在32位系統(tǒng)中size_t是4字節(jié)的,而在64位系統(tǒng) 中,size_t是8字節(jié)的,這樣利用該類型可以增強(qiáng)程序的可移植性。

            posted @ 2011-06-18 21:53 RTY 閱讀(400) | 評論 (0)編輯 收藏

            malloc

            原型:extern void *malloc(unsigned int num_bytes);
            用法:#include <malloc.h>
            或#include<stdlib.h>
            功能:分配長度為num_bytes字節(jié)的內(nèi)存塊
            說明:如果分配成功則返回指向被分配內(nèi)存的指針,否則返回空指針NULL。
            當(dāng)內(nèi)存不再使用時(shí),應(yīng)使用free()函數(shù)將內(nèi)存塊釋放。
            malloc的語法是:指針名=(數(shù)據(jù)類型*)malloc(長度),(數(shù)據(jù)類型*)表示指針.
            舉例

            // malloc.c
            #include <syslib.h>
            #include <malloc.h>
            main()
            {
            char *p;
            clrscr(); // clear screen
            p=(char *)malloc(100);
            if(p)
            printf("Memory Allocated at: %x",p);
            else
            printf("Not Enough Memory!\n");

            if(p)
            free(p);
            getchar();
            return 0;
            }

            malloc()函數(shù)的工作機(jī)制

            malloc函數(shù)的實(shí)質(zhì)體現(xiàn)在,它有一個(gè)將可用的內(nèi)存塊連接為一個(gè)長長的列表的所謂空閑鏈表。調(diào)用malloc函數(shù)時(shí),它沿連接表尋找一個(gè)大到足以滿足 用戶請求所需要的內(nèi)存塊。然后,將該內(nèi)存塊一分為二(一塊的大小與用戶請求的大小相等,另一塊的大小就是剩下的字節(jié))。接下來,將分配給用戶的那塊內(nèi)存?zhèn)? 給用戶,并將剩下的那塊(如果有的話)返回到連接表上。調(diào)用free函數(shù)時(shí),它將用戶釋放的內(nèi)存塊連接到空閑鏈上。到最后,空閑鏈會被切成很多的小內(nèi)存片 段,如果這時(shí)用戶申請一個(gè)大的內(nèi)存片段,那么空閑鏈上可能沒有可以滿足用戶要求的片段了。于是,malloc函數(shù)請求延時(shí),并開始在空閑鏈上翻箱倒柜地檢 查各內(nèi)存片段,對它們進(jìn)行整理,將相鄰的小空閑塊合并成較大的內(nèi)存塊。

            淺析malloc()的幾種實(shí)現(xiàn)方式

            malloc()是C語言中動態(tài)存儲管理的一組標(biāo)準(zhǔn)庫函數(shù)之一。其作用是在內(nèi)存的動態(tài)存儲區(qū)中分配一個(gè)長度為size的連續(xù)空間。其參數(shù)是一個(gè)無符號整形數(shù),返回值是一個(gè)指向所分配的連續(xù)存儲域的起始地址的指針。
            動態(tài)內(nèi)存分配就是指在程序執(zhí)行的過程中動態(tài)地分配或者回收存儲空間的分配內(nèi)存的方法。動態(tài)內(nèi)存 分配不像數(shù)組等靜態(tài)內(nèi)存分配方法那樣需要預(yù)先分配存儲空間,而是由系統(tǒng)根據(jù)程序的需要即時(shí)分配,且分配的大小就是程序要求的大小。本文簡單介紹動態(tài)內(nèi)存分 配函數(shù)malloc()及幾種實(shí)現(xiàn)方法。
            1. 簡介
            malloc()是C語言中動態(tài)存儲管理的一組標(biāo)準(zhǔn)庫函數(shù)之一。其作用是在內(nèi)存的動態(tài)存儲區(qū)中 分配一個(gè)長度為size的連續(xù)空間。其參數(shù)是一個(gè)無符號整形數(shù),返回值是一個(gè)指向所分配的連續(xù)存儲域的起始地址的指針。還有一點(diǎn)必須注意的是,當(dāng)函數(shù)未能 成功分配存儲空間(如內(nèi)存不足)就會返回一個(gè)NULL指針。所以在調(diào)用該函數(shù)時(shí)應(yīng)該檢測返回值是否為NULL并執(zhí)行相應(yīng)的操作。
            2. 函數(shù)說明
            C語言的動態(tài)存儲管理由一組標(biāo)準(zhǔn)庫函數(shù)實(shí)現(xiàn),其原型在標(biāo)準(zhǔn)文 件<stdlib.h>里描述,需要用這些功能時(shí)應(yīng)包含這個(gè)文件。與動態(tài)存儲分配有關(guān)的函數(shù)共有四個(gè),其中就包括存儲分配函數(shù) malloc()。函數(shù)原型是:void *malloc (size_t n);這里的size_t是標(biāo)準(zhǔn)庫里定義的一個(gè)類型,它是一個(gè)無符號整型。這個(gè)整型能夠滿足所有對存儲塊大小描述的需要,具體相當(dāng)于哪個(gè)整型由具體的C系 統(tǒng)確定。malloc的返回值為(void *)類型(這是通用指針的一個(gè)重要用途),它分配一片能存放大小為n的數(shù)據(jù)的存儲塊,返回對應(yīng)的指針值;如果不能滿足申請(找不到能滿足要求的存儲塊)就 返回NULL。在使用時(shí),應(yīng)該把malloc的返回值轉(zhuǎn)換到特定指針類型,賦給一個(gè)指針。
            注意,雖然這里的存儲塊是通過動態(tài)分配得到的,但是它的大小也是確定的,同樣不允許越界使用。 例如上面程序段分配的塊里能存n個(gè)雙精度數(shù)據(jù),隨后的使用就必須在這個(gè)范圍內(nèi)進(jìn)行。越界使用動態(tài)分配的存儲塊,尤其是越界賦值,可能引起非常嚴(yán)重的后果, 通常會破壞程序的運(yùn)行系統(tǒng),可能造成本程序或者整個(gè)計(jì)算機(jī)系統(tǒng)垮臺。
            下例是一個(gè)動態(tài)分配的例子:
            #include <stdio.h>
            #include<stdlib.h>
            main()
            {
            int count,*array; /*count是一個(gè)計(jì)數(shù)器,array是一個(gè)整型指針,也可以理解為指向一個(gè)整型數(shù)組的首地址*/
            count=100;
            if((array=(int *)malloc(count*sizeof(int))) == NULL)
            {
            printf("不能成功分配存儲空間。");
            exit(1);
            }
            for(count=0;count<10;count++) /*給數(shù)組賦值*/
            array[count]=count;
            for(count=0;count<10;count++) /*打印數(shù)組元素*/
            printf("%2d",array[count]);
            }
            上例中動態(tài)分配了10個(gè)整型存儲區(qū)域,然后進(jìn)行賦值并打印。例中if((array(int *) malloc (10*sizeof(int)))==NULL)語句可以分為以下幾步:
            1)分配10個(gè)整型的連續(xù)存儲空間,并返回一個(gè)指向其起始地址的整型指針
            2)把此整型指針地址賦給array
            3)檢測返回值是否為NULL
            3. malloc()工作機(jī)制
            malloc函數(shù)的實(shí)質(zhì)體現(xiàn)在,它有一個(gè)將可用的內(nèi)存塊連接為一個(gè)長長的列表的所謂空閑鏈表。 調(diào)用malloc函數(shù)時(shí),它沿連接表尋找一個(gè)大到足以滿足用戶請求所需要的內(nèi)存塊。然后,將該內(nèi)存塊一分為二(一塊的大小與用戶請求的大小相等,另一塊的 大小就是剩下的字節(jié))。接下來,將分配給用戶的那塊內(nèi)存?zhèn)鹘o用戶,并將剩下的那塊(如果有的話)返回到連接表上。調(diào)用free函數(shù)時(shí),它將用戶釋放的內(nèi)存 塊連接到空閑鏈上。到最后,空閑鏈會被切成很多的小內(nèi)存片段,如果這時(shí)用戶申請一個(gè)大的內(nèi)存片段,那么空閑鏈上可能沒有可以滿足用戶要求的片段了。于 是,malloc函數(shù)請求延時(shí),并開始在空閑鏈上翻箱倒柜地檢查各內(nèi)存片段,對它們進(jìn)行整理,將相鄰的小空閑塊合并成較大的內(nèi)存塊。
            4. malloc()在操作系統(tǒng)中的實(shí)現(xiàn)


                申請的時(shí)候?qū)嶋H上占用的內(nèi)存要比申請的大。因?yàn)槌龅目臻g是用來記錄對這塊內(nèi)存的管理信息。先看一下在《UNIX環(huán)境高級編程》中第七章的一段話:

               大多數(shù)實(shí)現(xiàn)所分配的存儲空間比所要求的要稍大一些,額外的空間用來記錄管理信息——分配塊的長度,指向下一個(gè)分配塊的指針等等。這就意味著如果寫過一個(gè)已 分配區(qū)的尾端,則會改寫后一塊的管理信息。這種類型的錯(cuò)誤是災(zāi)難性的,但是因?yàn)檫@種錯(cuò)誤不會很快就暴露出來,所以也就很難發(fā)現(xiàn)。將指向分配塊的指針向后移 動也可能會改寫本塊的管理信息。

               以上這段話已經(jīng)給了我們一些信息了。malloc()申請的空間實(shí)際我覺得就是分了兩個(gè)不同性質(zhì)的空間。一個(gè)就是用來記錄管理信息的空間,另外一個(gè)就是可用空間了。而用來記錄管理信息的實(shí)際上是一個(gè)結(jié)構(gòu)體。

            struct mem_control_block {
            int is_available;
            int size;
            };


            在 C 程序中,多次使用malloc () 和 free()。不過,您可能沒有用一些時(shí)間去思考它們在您的操作系統(tǒng)中是如何實(shí)現(xiàn)的。本節(jié)將向您展示 malloc 和 free 的一個(gè)最簡化實(shí)現(xiàn)的代碼,來幫助說明管理內(nèi)存時(shí)都涉及到了哪些事情。
            在大部分操作系統(tǒng)中,內(nèi)存分配由以下兩個(gè)簡單的函數(shù)來處理:
            void *malloc (long numbytes):該函數(shù)負(fù)責(zé)分配 numbytes 大小的內(nèi)存,并返回指向第一個(gè)字節(jié)的指針。
            void free(void *firstbyte):如果給定一個(gè)由先前的 malloc 返回的指針,那么該函數(shù)會將分配的空間歸還給進(jìn)程的“空閑空間”。
            malloc_init 將是初始化內(nèi)存分配程序的函數(shù)。它要完成以下三件事:將分配程序標(biāo)識為已經(jīng)初始化,找到系統(tǒng)中最后一個(gè)有效內(nèi)存地址,然后建立起指向我們管理的內(nèi)存的指針。這三個(gè)變量都是全局變量:
            清單 1. 我們的簡單分配程序的全局變量
            int has_initialized = 0;
            void *managed_memory_start;
            void *last_valid_address;
            如前所述,被映射的內(nèi)存的邊界(最后一個(gè)有效地址)常被稱為系統(tǒng)中斷點(diǎn)或者 當(dāng)前中斷點(diǎn)。在很多 UNIX? 系統(tǒng)中,為了指出當(dāng)前系統(tǒng)中斷點(diǎn),必須使用 sbrk(0) 函數(shù)。 sbrk 根據(jù)參數(shù)中給出的字節(jié)數(shù)移動當(dāng)前系統(tǒng)中斷點(diǎn),然后返回新的系統(tǒng)中斷點(diǎn)。使用參數(shù) 0 只是返回當(dāng)前中斷點(diǎn)。這里是我們的 malloc 初始化代碼,它將找到當(dāng)前中斷點(diǎn)并初始化我們的變量:
            清單 2. 分配程序初始化函數(shù)
            /* Include the sbrk function */
            #include
            void malloc_init()
            {
            /* grab the last valid address from the OS */
            last_valid_address = sbrk(0);
            /* we don't have any memory to manage yet, so
            *just set the beginning to be last_valid_address
            */
            managed_memory_start = last_valid_address;
            /* Okay, we're initialized and ready to go */
            has_initialized = 1;
            }
            現(xiàn)在,為了完全地管理內(nèi)存,我們需要能夠追蹤要分配和回收哪些內(nèi)存。在對內(nèi)存塊進(jìn)行了 free 調(diào)用之后,我們需要做的是諸如將它們標(biāo)記為未被使用的等事情,并且,在調(diào)用 malloc 時(shí),我們要能夠定位未被使用的內(nèi)存塊。因此, malloc 返回的每塊內(nèi)存的起始處首先要有這個(gè)結(jié)構(gòu):
            清單 3. 內(nèi)存控制塊結(jié)構(gòu)定義
            struct mem_control_block {
            int is_available;
            int size;
            };
            現(xiàn)在,您可能會認(rèn)為當(dāng)程序調(diào)用 malloc 時(shí)這會引發(fā)問題 —— 它們?nèi)绾沃肋@個(gè)結(jié)構(gòu)?答案是它們不必知道;在返回指針之前,我們會將其移動到這個(gè)結(jié)構(gòu)之后,把它隱藏起來。這使得返回的指針指向沒有用于任何其他用途的 內(nèi)存。那樣,從調(diào)用程序的角度來看,它們所得到的全部是空閑的、開放的內(nèi)存。然后,當(dāng)通過 free() 將該指針傳遞回來時(shí),我們只需要倒退幾個(gè)內(nèi)存字節(jié)就可以再次找到這個(gè)結(jié)構(gòu)。
            在討論分配內(nèi)存之前,我們將先討論釋放,因?yàn)樗唵巍榱酸尫艃?nèi)存,我們必須要做的惟一一件事情就是,獲得我們給出的指針,回退 sizeof(struct mem_control_block) 個(gè)字節(jié),并將其標(biāo)記為可用的。這里是對應(yīng)的代碼:
            清單 4. 解除分配函數(shù)
            void free(void *firstbyte) {
            struct mem_control_block *mcb;
            /* Backup from the given pointer to find the
            * mem_control_block
            */
            mcb = firstbyte - sizeof(struct mem_control_block);
            /* Mark the block as being available */
            mcb->is_available = 1;
            /* That's It! We're done. */
            return;
            }
            如您所見,在這個(gè)分配程序中,內(nèi)存的釋放使用了一個(gè)非常簡單的機(jī)制,在固定時(shí)間內(nèi)完成內(nèi)存釋放。分配內(nèi)存稍微困難一些。以下是該算法的略述:
            清單 5. 主分配程序的偽代碼
            1. If our allocator has not been initialized, initialize it.
            2. Add sizeof(struct mem_control_block) to the size requested.
            3. start at managed_memory_start.
            4. Are we at last_valid address?
            5. If we are:
            A. We didn't find any existing space that was large enough
            -- ask the operating system for more and return that.
            6. Otherwise:
            A. Is the current space available (check is_available from
            the mem_control_block)?
            B. If it is:
            i) Is it large enough (check "size" from the
            mem_control_block)?
            ii) If so:
            a. Mark it as unavailable
            b. Move past mem_control_block and return the
            pointer
            iii) Otherwise:
            a. Move forward "size" bytes
            b. Go back go step 4
            C. Otherwise:
            i) Move forward "size" bytes
            ii) Go back to step 4
            我們主要使用連接的指針遍歷內(nèi)存來尋找開放的內(nèi)存塊。這里是代碼:
            清單 6. 主分配程序
            void *malloc(long numbytes) {
            /* Holds where we are looking in memory */
            void *current_location;
            /* This is the same as current_location, but cast to a
            * memory_control_block
            */
            struct mem_control_block *current_location_mcb;
            /* This is the memory location we will return. It will
            * be set to 0 until we find something suitable
            */
            void *memory_location;
            /* Initialize if we haven't already done so */
            if(! has_initialized) {
            malloc_init();
            }
            /* The memory we search for has to include the memory
            * control block, but the users of malloc don't need
            * to know this, so we'll just add it in for them.
            */
            numbytes = numbytes + sizeof(struct mem_control_block);
            /* Set memory_location to 0 until we find a suitable
            * location
            */
            memory_location = 0;
            /* Begin searching at the start of managed memory */
            current_location = managed_memory_start;
            /* Keep going until we have searched all allocated space */
            while(current_location != last_valid_address)
            {
            /* current_location and current_location_mcb point
            * to the same address. However, current_location_mcb
            * is of the correct type, so we can use it as a struct.
            * current_location is a void pointer so we can use it
            * to calculate addresses.
            */
            current_location_mcb =
            (struct mem_control_block *)current_location;
            if(current_location_mcb->is_available)
            {
            if(current_location_mcb->size >= numbytes)
            {
            /* Woohoo! We've found an open,
            * appropriately-size location.
            */
            /* It is no longer available */
            current_location_mcb->is_available = 0;
            /* We own it */
            memory_location = current_location;
            /* Leave the loop */
            break;
            }
            }
            /* If we made it here, it's because the Current memory
            * block not suitable; move to the next one
            */
            current_location = current_location +
            current_location_mcb->size;
            }
            /* If we still don't have a valid location, we'll
            * have to ask the operating system for more memory
            */
            if(! memory_location)
            {
            /* Move the program break numbytes further */
            sbrk(numbytes);
            /* The new memory will be where the last valid
            * address left off
            */
            memory_location = last_valid_address;
            /* We'll move the last valid address forward
            * numbytes
            */
            last_valid_address = last_valid_address + numbytes;
            /* We need to initialize the mem_control_block */
            current_location_mcb = memory_location;
            current_location_mcb->is_available = 0;
            current_location_mcb->size = numbytes;
            }
            /* Now, no matter what (well, except for error conditions),
            * memory_location has the address of the memory, including
            * the mem_control_block
            */
            /* Move the pointer past the mem_control_block */
            memory_location = memory_location + sizeof(struct mem_control_block);
            /* Return the pointer */
            return memory_location;
            }
            這就是我們的內(nèi)存管理器。現(xiàn)在,我們只需要構(gòu)建它,并在程序中使用它即可。
            5. malloc()的其他實(shí)現(xiàn)
            malloc() 的實(shí)現(xiàn)有很多,這些實(shí)現(xiàn)各有優(yōu)點(diǎn)與缺點(diǎn)。在設(shè)計(jì)一個(gè)分配程序時(shí),要面臨許多需要折衷的選擇,其中包括:
            分配的速度。
            回收的速度。
            有線程的環(huán)境的行為。
            內(nèi)存將要被用光時(shí)的行為。
            局部緩存。
            簿記(Bookkeeping)內(nèi)存開銷。
            虛擬內(nèi)存環(huán)境中的行為。
            小的或者大的對象。
            實(shí)時(shí)保證。
            每一個(gè)實(shí)現(xiàn)都有其自身的優(yōu)缺點(diǎn)集合。在我們的簡單的分配程序中,分配非常慢,而回收非常快。另外,由于它在使用虛擬內(nèi)存系統(tǒng)方面較差,所以它最適于處理大的對象。
            還有其他許多分配程序可以使用。其中包括:
            Doug Lea Malloc:Doug Lea Malloc 實(shí)際上是完整的一組分配程序,其中包括 Doug Lea 的原始分配程序,GNU libc 分配程序和 ptmalloc。 Doug Lea 的分配程序有著與我們的版本非常類似的基本結(jié)構(gòu),但是它加入了索引,這使得搜索速度更快,并且可以將多個(gè)沒有被使用的塊組合為一個(gè)大的塊。它還支持緩存, 以便更快地再次使用最近釋放的內(nèi)存。 ptmalloc 是 Doug Lea Malloc 的一個(gè)擴(kuò)展版本,支持多線程。在本文后面的 參考資料部分中,有一篇描述 Doug Lea 的 Malloc 實(shí)現(xiàn)的文章。
            BSD Malloc:BSD Malloc 是隨 4.2 BSD 發(fā)行的實(shí)現(xiàn),包含在 FreeBSD 之中,這個(gè)分配程序可以從預(yù)先確實(shí)大小的對象構(gòu)成的池中分配對象。它有一些用于對象大小的 size 類,這些對象的大小為 2 的若干次冪減去某一常數(shù)。所以,如果您請求給定大小的一個(gè)對象,它就簡單地分配一個(gè)與之匹配的 size 類。這樣就提供了一個(gè)快速的實(shí)現(xiàn),但是可能會浪費(fèi)內(nèi)存。在 參考資料部分中,有一篇描述該實(shí)現(xiàn)的文章。
            Hoard:編寫 Hoard 的目標(biāo)是使內(nèi)存分配在多線程環(huán)境中進(jìn)行得非常快。因此,它的構(gòu)造以鎖的使用為中心,從而使所有進(jìn)程不必等待分配內(nèi)存。它可以顯著地加快那些進(jìn)行很多分配和回收的多線程進(jìn)程的速度。在 參考資料部分中,有一篇描述該實(shí)現(xiàn)的文章。
            眾多可用的分配程序中最有名的就是上述這些分配程序。如果您的程序有特別的分配需求,那么您可能更愿意編寫一個(gè)定制的能匹配您的程序內(nèi)存分配方式的分配程序。不過,如果不熟悉分配程序的設(shè)計(jì),那么定制分配程序通常會帶來比它們解決的問題更多的問題。
            6. 結(jié)束語
            前面已經(jīng)提過,多次調(diào)用malloc()后空閑內(nèi)存被切成很多的小內(nèi)存片段,這就使得用戶在申 請內(nèi)存使用時(shí),由于找不到足夠大的內(nèi)存空間,malloc()需要進(jìn)行內(nèi)存整理,使得函數(shù)的性能越來越低。聰明的程序員通過總是分配大小為2的冪的內(nèi)存 塊,而最大限度地降低潛在的malloc性能喪失。也就是說,所分配的內(nèi)存塊大小為4字節(jié)、8字節(jié)、16字節(jié)、18446744073709551616 字節(jié),等等。這樣做最大限度地減少了進(jìn)入空閑鏈的怪異片段(各種尺寸的小片段都有)的數(shù)量。盡管看起來這好像浪費(fèi)了空間,但也容易看出浪費(fèi)的空間永遠(yuǎn)不會 超過50%。
            參考文獻(xiàn):
            [1] Jonathan Bartlett,內(nèi)存管理內(nèi)幕. developerWorks 中國,2004年11月
            [2] Jan Lindblad,內(nèi)存碎片處理技術(shù). EDN電子設(shè)計(jì)技術(shù),2004年10月08日

            轉(zhuǎn)自:http://baike.baidu.com/view/736228.htm

            posted @ 2011-06-18 20:20 RTY 閱讀(897) | 評論 (0)編輯 收藏

            僅列出標(biāo)題
            共31頁: First 13 14 15 16 17 18 19 20 21 Last 
            精品国产综合区久久久久久 | 色综合久久88色综合天天 | 一本久久a久久精品综合香蕉| 国产精品99久久久久久人| 无码国内精品久久人妻蜜桃| 伊人久久五月天| 久久亚洲精品国产精品婷婷| 香蕉99久久国产综合精品宅男自 | 日本久久中文字幕| 青青草原综合久久| 久久精品成人免费看| 国内精品久久久久| 伊人久久综合热线大杳蕉下载| 久久91精品国产91久久小草| 久久99国产精品久久| 久久精品免费观看| 99久久99久久精品国产片| 国产69精品久久久久99| 久久精品国产福利国产琪琪| 色婷婷综合久久久久中文字幕| 亚洲午夜福利精品久久| 久久综合亚洲色一区二区三区| 少妇久久久久久久久久| 国产精品久久久久久| 国产精品99久久久久久www| 国产福利电影一区二区三区久久久久成人精品综合 | 久久精品亚洲中文字幕无码麻豆| 久久亚洲私人国产精品| 久久er国产精品免费观看2| 久久国产免费| 久久夜色精品国产噜噜麻豆| 99久久免费国产精品| 亚洲中文字幕伊人久久无码| WWW婷婷AV久久久影片| 久久播电影网| 久久综合88熟人妻| 国产午夜精品久久久久九九| 久久天天躁狠狠躁夜夜avapp| 国产成人精品白浆久久69| 久久综合亚洲色HEZYO国产| 久久精品亚洲一区二区三区浴池|