??xml version="1.0" encoding="utf-8" standalone="yes"?> 该错误主要是׃静态库在VC6~译而主E序在VC2005~译Q大家用的CRT不同。解军_法,代码中增?/p>
#ifdef __cplusplus 此错误的产生Ҏ(gu)Q?br>
在VC6的stdio.h之中有如下定?/p>
_CRTIMP extern FILE _iob[]; stdin、stdout、stderr是通过查_iob数组得到的。所以,VC6~译的程序、静态库只要用到了printf、scanf之类的函敎ͼ都要链接_iob数组?/p>
而在vc2005中,stdio.h中变成了 _CRTIMP FILE * __cdecl __iob_func(void); _iob数组不再是显式的暴露出来了,需要调用__iob_func()函数获得。所以vc6的静态库链接VC2005的Cq行库就会找不到_iob数组. Let's start with the reason why I
wrote this article. One day, a colleague asked me to help him debug
a problem he had. So I was watching him stepping in
his code, when I noticed the following line:
He did this, because he wanted to know the error code, if the previous
function failed. He was adding this line every time he wanted to know the error
code. I advised him to remove all those lines and use the @ERR pseudoregister in
his watch window. He didn't know what it was and asking around in the office, a
lot of other people didn't. So I came up with this article for people who have never
heard of pseudoregisters. A pseudoregister is not an actual hardware
register, but is displayed as though it were a hardware register. With a
pseudoregister, you can see and use certain values (error codes,
thread information block...) in the debugger. Let's have a look at the @ERR pseudoregister. Fire up your debugger with your
favourite home-written application. Put a breakpoint in your code so that the
debugger will break execution. Open the watch window if it isn't already (do
this by right clicking on some empty toolbar space, and select "Watch" from this
list). Add @ERR in this watch window. You should see 0 in the Value column. Now
step through your code, and watch this value. It will always show the
If you want to test this, but your code doesn't
have any errors, I advise to put some in (but don't forget to remove them
afterwards). You can insert something like this: If you step over this line, you'll see that the @ERR value changed to 2. Go to Tools->Error Lookup to see
what this error value means ("The system cannot find the file specified" if you
were wondering). Lazy bums like me, and smart lads / lasses like you can change
the @ERR pseudoregister to @ERR,hr . Doing this will change the value of the
pseudoregister to the error string. Now you even don't have to lookup the error.
I leave the @ERR,hr in the watch window all the time. Pseudoregisters can also
be used in conditional expressions. To try this out, put following lines after
the Put a breakpoint on the Just for the very curious (and
otherwise totally irrelevant to this article) : what does @ERR do? How does it
get the error number? As it turns out, @ERR does exactly the same thing as
So The @ERR pseudoregister is not the only one that exists. Another important pseudoregister
is @TIB. This is the thread information block for the current thread and is
extremely helpful in multi-threaded debugging. If you place a breakpoint in a
function that is called by multiple threads, the debugger will break execution
every time no matter which thread passes the breakpoint. Even if you're stepping
through your code, the debugger can jump to the breakpoint if another thread
called the function. To solve this, you'll need to do the following. If
execution breaks in the thread you want, add @TIB in the watch window. You will
see some value like "0x7ffa6000" or "2147115008" in regular display. Go to the
breakpoint menu (Alt-F9) and select the breakpoint. You can now add the
This doesn't work in Windows 98 though. For Windows 98,
you'll need to look at the Intel CPU FS register, which is unique for each
thread. You can use the expression
Pseudoregister Description @ERR Last error value; the same value returned by the @TIB Thread information block for the current thread; necessary because the debugger doesn't handle the "FS:0" format @CLK Undocumented clock register; usable only in the Watch window @EAX, @EBX, @ECX, @EDX, @ESI, @EDI, @EIP, @ESP, @EBP, @EFL Intel CPU registers @CS, @DS, @ES, @SS, @FS, @GS Intel CPU segment registers @ST0, @ST1, @ST2, @ST3, @ST4, @ST5, @ST6, @ST7 Intel CPU floating-point registers ?#8220;查找”?#8220;在文件中查找”?#8220;在文件中替换”对话框中Q可使用下列正则表达式来改进和扩展搜索?/p>
可用下列表辑ּ匚w搜烦字符串中的字W或数字Q?/p>
?#8220;替换”表达式中Q\0 插入整个匚w的文本?/p>
下表列出按标?Unicode 字符属性进行匹配的语法。两个字母的~写词与 Unicode 字符属性数据库中所列的一栗可这些指定ؓ字符集的一部分。例如,表达?[:Nd:Nl:No] 匚wMU类的数字?/p>
除标?Unicode 字符属性外Q还可以指定下列附加属性。可这些属性指定ؓ字符集的一部分?/p>
C++的辅助工L多,我们分门别类的ؓ大家作介l: 4.1 文c?/p>
(1) Doxygen Doxygen是一U适合C风格语言Q如C++、C、IDL、Java甚至包括C#和PHPQ的?br>开放源码的、基于命令行的文生器?/p>
(2) C++2HTML 参考站点:http://www.bedaux.net/cpp2html/ 把C++代码变成语法高亮的HTML (3) CodeColorizer 参考站点:http://www.chami.com/colorizer/ 它能把好几种语言的源代码着色ؓHTML (4) Doc-O-Matic 参考站点:http://www.doc-o-matic.com/ Doc-O_MaticZ的C/C++QC++.netQDelphi/Pascal, VB.NETQC#和JavaE序 (5) DocVizor 参考站点:http://www.ucancode.net/Products/DocBuilder/Features.htm DocVizor满了面向对象Y件开发者的基本要求——它让我们能够看到C++工程 (6) SourcePublisher C++ 参考站点:http://www.scitools.com/sourcepublisher_c.html l源代码产生提供快速直观的HTML报表Q包括代码,cdơ结构,调用和被?br>用树Q包含和被包含树。支持多U操作系l?/p>
(7) Understand 参考站点:http://www.scitools.com/ucpp.html 分析M规模的C或者C++工程Q帮助我们更好的理解以及~写文档?/p>
4.2 代码c?/p>
(1) CC-Rider CC-Rider是用于C/C++E序强大的代码可视化工具Q通过交互式浏览、编辑及?br>动文件来促进E序的维持和发展?/p>
(2) CodeInspect 一U新的C/C++代码分析工具。它查我们的源代码找出非标准的,可能的,?br>及普通的错误代码?/p>
(3) CodeWizard 先进的C/C++源代码分析工P使用过500个编码规范自动化地标明危险的Q?br>但是~译器不能检查到的代码结构?/p>
(4) C++ Validation Test Suites 参考站点:http://www.plumhall.com/suites.html 一l用于测试编译器和库对于标准dE度的代码库?/p>
(5) CppRefactory 参考站点:http://cpptool.sourceforge.net/ CPPRefactory是一个得开发者能够重构他们的C++代码的程序。目的是使得C (6) Lzz 参考站点:http://www.lazycplusplus.com/ Lzz是一个自动化许多C++~程中的体力zȝ工具。它能够节省我们许多事gq?br>且得编码更加有乐趣。给Zpd的声明,Lzz会给我们创徏头文件和源文件?/p>
(7) QA C++ Generation 2000 参考站点:http://www.programmingresearch.com/solutions/qacpp.htm 它关注面向对象的C++源代码,Ҏ(gu)关于设计Q效率,可靠性,可维护性的部分 (8) s-mail project - Java to C++DOL 参考站点:http://sadlocha.strefa.pl/s-mail/ja2dol.html 把Java源代码翻译ؓ相应的C++源代码的命o行工兗?/p>
(9) SNIP from Cleanscape Software International 参考站点:http://www.cleanscape.net/stdprod/snip/index.html 一个填q编码和设计之间沟壑的易于用的C++开发工P节省大量~辑和调?br>的事Ӟ它还使得开发者能够指定设计模式作为对象模型,自动从对象模型中产生 (10) SourceStyler C++ 参考站点:http://www.ochresoftware.com/ 对C/C++源代码提供完整的格式化和排版控制的工兗提供多?5个的格式化?br>以及完全支持ANSI C++?/p>
4.3 ~译c?/p>
(1) Compilercache 参考站点:http://www.erikyyy.de/compilercache/ Compilercache是一个对你的C和C++~译器的装脚本。每ơ我们进行编译,?br>装脚本,把编译的l果攑օ~存Q一旦编译相同的东西Q结果将从缓存中取出而不 (2) Ccache Ccache是一个编译器~存。它使用h像C/C++~译器的~存预处理器Q编?br>速度通常能提高普通编译过E的5~10倍?/p>
(3) Cmm (C++ with MultiMethods) 参考站点:http://www.op59.net/cmm/cmm-0.28/users.html q是一UC++语言的扩展。读入Cmm源代码输出C++的源代码Q功能是对C++语言 (4) The Frost Project Forst使得你能够在C++E序中像原生的C++Ҏ(gu)一样用multimethod以及虚函 4.4 试和调试类 (1) CPPUnit CppUnit 是个Z LGPL 的开源项目,最初版本移植自 JUnitQ是一个非怼 (2) C++Test C++ Test是一个单元测试工P它自动化了C和C++c,函数或者组件的试?/p>
参考站点:http://www.iplbath.com/products/tools/pt400.shtml 设计的目的是Z满在合理的l济开销下用这个工具可以让开发工E师开 (4) Purify 参考站点:http://www-900.ibm.com/cn/software/rational/products/purif IBM Rational PurifyPlus是一套完整的q行时分析工P旨在提高应用E序?br>可靠性和性能。PurifyPlus内存错误和泄漏、应用程序性能描述、代码覆?br>分析{功能组合在一个单一、完整的工具包中?/p>
(5) BoundsChecker BoundsChecker是一个C++q行旉误检和调试工具。它通过在Visual Studi 一个自动化的运行时E序试工具Q检查难以察觉的错误,如内存覆盖,内存?br>漏,内存分配错误Q变量初始化错误Q变量定义冲H,指针错误Q库错误Q逻辑?br>误和法错误{?/p>
(7) GlowCode GlowCode包括内存泄漏查,code profilerQ函数调用跟t等功能。给C++开 (8) Stack Spy 参考站点:http://www.imperioustech.com/ 它能捕捉stack corruption, stack over run, stack overflow{有x的错 ------------------------------------------------------------------------ 5Q库 在C++中,库的C是非帔R的。C++之父 Bjarne Stroustrup先生多次表示?br>设计库来扩充功能要好q设计更多的语法的言论。现实中QC++的库门类J多Q解?br>的问题也是极其广泛,库从轻量U到重量U的都有。不都是让人眼界大开Q亦?br>是望而生叹的思维C。由于库的数量非常庞大,而且限于W者水qI其中很多q?br>不了解。所以文中所提的一些库都是比较著名的大型库?/p>
5.1 标准?/p>
标准库中提供了C++E序的基本设施。虽然C++标准库随着C++标准折腾了许多年 (1) Dinkumware C++ Library 参考站点:http://www.dinkumware.com/ P.J. Plauger~写的高品质的标准库。P.J. Plauger博士是Dr. Dobb'sE序?br>计杰出奖的获得者。其~写的库长期被Microsoft采用Qƈ且最qB(ti)orland也取得了 (2) RogueWave Standard C++ Library 参考站点:http://www.roguewave.com/ q个库在Borland C++ Builder的早期版本中曄被采用,后来被其他的库给?br>换了。笔者不推荐使用?/p>
(3) SGI STL 参考站点:http://www.roguewave.com/ SGI公司的C++标准模版库?/p>
(4) STLport SGI STL库的跨^台可UL版本?/p>
5.2 “?#8221;标准?nbsp;- Boost 国内镜像Q?a class=contentlink target=_blank>http://www.c-view.org/tech/lib/boost/index.htm Boost库是一个经q千锤百点{可UL、提供源代码的C++库,作ؓ标准库的?br>备,是C++标准化进E的发动Z一?nbsp;Boost库由C++标准委员会库工作l成员发?br>Q在C++C中媄响甚大,其成员已q?000人?nbsp;Boost库ؓ我们带来了最新、最酗?br>最实用的技术,是不折不扣的“?#8221;标准库?/p>
Boost中比较有名气的有q么几个库: Regex 正则表达式库 Spirit LL parser frameworkQ用C++代码直接表达EBNF Graph 囄件和法 Lambda 在调用的地方定义短小匿名的函数对象,很实用的functional功能 concept check 查泛型编E中的concept 用模板实现的元编E框?/p>
可移植的C++多线E库 把C++cd函数映射到Python之中 Pool 内存池管?/p>
5个智能指针,学习指针必读Q一份不错的参考是来自CUJ的文章: Smart Pointers in BoostQ哦Q这文章可以查刎ͼCUJ是提供在U浏览的?br>中文版见W者在《Dr. Dobb's Journal软g研发杂志》第7辑上的译文?/p>
BoostM来说是实用h(hun)值很高,质量很高的库。ƈ且由于其对跨q_的强调, 5.3 GUI 在众多C++的库中,GUI部分的库是比较J荣Q也比较引h注目的。在实际开 (1) MFC 大名鼎鼎的微软基cdQMicrosoft Foundation ClassQ。大凡学qVC++?br>人都应该知道q个库。虽然从技术角度讲QMFC是不大漂亮的Q但是它构徏于Windo (2) QT 参考网站:http://www.trolltech.com/ Qt是Trolltech公司的一个多q_的C++囑Ş用户界面应用E序框架。它提供l?br>应用E序开发者徏立艺术的图形用L面所需的所用功能。Qt是完全面向对象的 (3) WxWindows 参考网站:http://www.wxwindows.org/ 跨^台的GUI库。因为其cdơ极像MFCQ所以有文章介绍从MFC到WxWindows?br>代码UL以实现跨q_的功能。通过多年的开发也是一个日完善的GUI库,支持?br>样不׃前面两个库。ƈ且是完全开放源代码的。新q的C++ Builder X的GUI设计 (4) Fox 参考网站:http://www.fox-toolkit.org/ 开放源代码的GUI库。作者从自己亲n的开发经验中得出了一个理想的GUI库应 ZATL的一个库。因Z用了大量ATL的轻量手法Q模板等技术,在代码尺 (6) GTK 参考网站:http://gtkmm.sourceforge.net/ GTK是一个大名鼎鼎的C的开源GUI库。在Linux世界中有Gnomeq样的杀手应用?br>而GTK是q个库的C++装版本?/p>
5.4 |络通信 (1) ACE 参考网站:http://www.cs.wustl.edu/~schmidt/ACE.html C++库的代表Q超重量U的|络通信开发框架。ACE自适配通信环境QAdaptive (2) StreamModule 参考网站:http://www.omnifarious.org/StrMod/ 设计用于化编写分布式E序的库。尝试着使得~写处理异步行ؓ的程序更?br>易,而不是用同步的外壛_起异步的本质?/p>
(3) SimpleSocket 参考网站:http://home.hetnet.nl/~lcbokkers/simsock.htm q个cd让编写基于socket的客?服务器程序更加容易?/p>
(4) A Stream Socket API for C++ 参考网站:http://www.pcs.cnu.edu/~dgame/sockets/socketsC++/sockets.h 又一个对Socket的封装库?/p>
5.5 XML (1) Xerces 参考网站:http://xml.apache.org/xerces-c/ Xerces-C++ 是一个非常健壮的XML解析器,它提供了验证Q以及SAX和DOM API (2) XMLBooster 参考网站:http://www.xmlbooster.com/ q个库通过产生特制的parser的办法极大的提高了XML解析的速度Qƈ且能够 (3) Pull Parser 参考网站:http://www.extreme.indiana.edu/xgws/xsoap/xpp/ q个库采用pullҎ(gu)的parser。在每个SAX的parser底层都有一个pull的parse 参考网站:http://xml.apache.org/xalan-c/ Xalan是一个用于把XML文转换为HTMLQ纯文本或者其他XMLcd文档的XSLT?br>理器?/p>
(5) CMarkup 参考网站:http://www.firstobject.com/xml.htm q是一U用EDOM的XML解析器。在很多思\上面非常灉|实用。值得大家在D (6) libxml++ http://libxmlplusplus.sourceforge.net/ libxml++是对著名的libxml XML解析器的C++装版本 5.6 U学计算 (1) Blitz++ 参考网站:http://www.oonumerics.org/blitz/ Blitz++ 是一个高效率的数D函数库Q它的设计目的是希望建立一套既?br>像C++ 一h便,同时又比Fortran速度更快的数D环境。通常Q用C++所写出 (2) POOMA 参考网站:http://www.codesourcery.com/pooma/pooma POOMA是一个免费的高性能的C++库,用于处理q行式科学计。POOMA的面向对 (3) MTL 参考网站:http://www.osl.iu.edu/research/mtl/ Matrix Template Library(MTL)是一个高性能的泛型组件库Q提供了各种格式 (4) CGAL 参考网站:http://www.cgal.org/ Computational Geometry Algorithms Library的目的是把在计算几何斚w的大 5.7 游戏开?/p>
(1) Audio/Video 3D C++ Programming Library 参考网站:http://www.galacticasoftware.com/products/av/ AV3D是一个跨q_Q高性能的C++库。主要的Ҏ(gu)是提供3D囑ŞQ声效支持(S (2) KlayGE 参考网站:http://home.g365.net/enginedev/ 国内游戏开发高手自qC++开发的游戏引擎。KlayGE是一个开放源代码、跨q?br>台的游戏引擎Qƈ使用Python作脚本语a。KlayGE在LGPL协议下发行。感谢龚敏敏 (3) OGRE OGREQ面向对象的囑Ş渲染引擎Q是用C++开发的Q用灵zȝ面向对象3D引擎 5.8 U程 (1) C++ Threads 参考网站:http://threads.sourceforge.net/ q个库的目标是给E序员提供易于用的c,q些c被l承以提供在Linux环境 (2) ZThreads 参考网站:http://zthread.sourceforge.net/ 一个先q的面向对象Q跨q_的C++U程和同步库?/p>
5.9 序列?/p>
(1) s11n 参考网站:http://s11n.net/ 一个基于STL的C++库,用于序列化PODQSTL容器以及用户定义的类型?/p>
(2) Simple XML Persistence Library 参考网站:http://sxp.sourceforge.net/ q是一个把对象序列化ؓXML的轻量的C++库?/p>
5.10 字符?/p>
(1) C++ Str Library 参考网站:http://www.utilitycode.com/str/ 操作字符串和字符的库Q支持Windows和支持gcc的多U^台。提供高度优化的 (2) Common Text Transformation Library 参考网站:http://cttl.sourceforge.net/ q是一个解析和修改STL字符串的库。CTTL substringcd以用来比较,插入Q?br>替换以及用EBNF的语法进行解析?/p>
(3) GRETA 参考网站:http://research.microsoft.com/projects/greta/ q是由微软研I的研Ih员开发的处理正则表达式的库。在型匚w的情?br>下有非常优秀的表现?/p>
5.11 l合 (1) P::Classes 参考网站:http://pclasses.com/ 一个高度可UL的C++应用E序框架。当前关注类型和U程安全的signal/slot (2) ACDK - Artefaktur Component Development Kit 参考网站:http://acdk.sourceforge.net/ q是一个^台无关的C++lg框架Q类gJava或?NET中的框架Q反机Ӟ (3) dlib C++ library 参考网站:http://www.cis.ohio-state.edu/~kingd/dlib/ 各种各样的类的一个综合。大整数QSocketQ线E,GUIQ容器类,以及览?br>录的API{等?/p>
(4) Chilkat C++ Libraries 参考网站:http://www.chilkatsoft.com/cpp_libraries.asp q是提供zipQe-mailQ编码,S/MIMEQXML{方面的库?/p>
(5) C++ Portable Types Library (PTypes) 参考网站:http://www.melikyan.com/ptypes/ q是STL的比较简单的替代品,以及可移植的多线E和|络库?/p>
(6) LFC 参考网站:http://lfc.sourceforge.net/ 哦,q又是一个尝试提供一切的C++?/p>
5.12 其他?/p>
(1) Loki 参考网站:http://www.moderncppdesign.com/ 哦,你可能抱怨我早该和Boost一起介l它Q一个实验性质的库。作者在loki?br>把C++模板的功能发挥到了极致。ƈ且尝试把cM设计模式q样思想层面的东襉K过 (2) ATL ATL(Active Template Library) 是一l小巧、高效、灵zȝc,q些cMؓ创徏可互操作的COMlg提供了基本的 (3) FC++: The Functional C++ Library q个库提供了一些函数式语言中才有的要素。属于用库来扩充语言的一个代?br>作。如果想要在OOP之外L另一分的乐趣Q可以去看看函数式程序设计的世界。大 (4) FACT! 参考网站:http://www.kfa-juelich.de/zam/FACT/start/index.html 另外一个实现函数式语言Ҏ(gu)的?/p>
(5) Crypto++ 提供处理密码Q消息验证,单向hashQ公匙加密系l等功能的免费库?/p>
q有很多非常Ȁ动h心或者是极其实用的C++库,限于我们的水q以及文章的?br>q不能包括进来。在对于q些已经包含q来的库的介l中Q由于ƈ不是每一个我?br>都用过Q所以难免有偏颇之处Q请读者见谅?/p>
extern "C"
#endif
FILE _iob[3] = {__iob_func()[0], __iob_func()[1], __iob_func()[2]};
#define stdin (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])
#define stdin (&__iob_func()[0])
#define stdout (&__iob_func()[1])
#define stderr (&__iob_func()[2])
通过重新定义
FILE _iob[3] = {__iob_func()[0], __iob_func()[1], __iob_func()[2]};
把vc6需要用到的_iob数组搞出来了
]]> Collapse
int test = GetLastError();
What is a pseudoregister anyway?
GetLastError()
number for the current thread. So if something goes wrong in your
code, this value will change. Collapse
FILE *fp = fopen("c:\\a_file_that_does_not_exist.txt", "r");
Conditional Expressions
fopen
: Collapse
if (fp)
{
fclose(fp);
}if (fp)
line. Go to Edit->Breakpoints (or
press Alt-F9). Select the breakpoint you just inserted and press the "Condition"
button. Here, you can enter the @ERR==2
condition. Now start the debugger. The
debugger will break on this breakpoint if fopen()
failed because it couldn't find
the file. If the file does exist, the debugger won't break, even if it
encountered another error (say error 4: could not open the file). Try this out by
running the code (not stepping) after creating, and deleting the
"a_file_that_does_not_exist.txt" file on c:\.GetLastError()
does. These functions have a whopping 3 lines of assembly code: Collapse
mov eax,fs:[00000018h]
mov eax,dword ptr [eax+34h]
ret@ERR
grabs the DWORD
at
offset 0x34 in the thread environment block pointed to by fs:[18h].The @TIB pseudoregister
@TIB==0x7ffa6000
condition filter. Doing this, the debugger will only break
execution for this thread. All other threads using the same function will not
result in a break.@FS==value
Complete list of pseudoregisters
GetLastError()
API function
]]>
最开始?pragma section(SECNAME,long,read)的方法,把某个函数加入到某个section中,因ؓCRT是按照section的字母序执行的,q个Ҏ(gu)
在exe中执行的很好Q不q的是我们是在一个dll中,q个Ҏ(gu)不奏效?br>
最后查看msdnQ写道:如果是用dllQ?strong>#pragma init_seg
#pragma init_seg(compiler)
_CRTIMP2 MemoryManager MemMnger;
q样Q初始化工作在编译器初始化的时候就执行了,q断炚w断不C
]]>
注意???在将下列M表达式用作搜索条件的一部分之前Q必d“查找”?#8220;在文件中查找”?#8220;在文件中替换”对话框中选择“使用”复选框?/blockquote>
表达?/th>
语法
说明
M字符
.
匚w除换行符外的M一个字W?/td>
最?0 Ҏ(gu)更多
*
匚w前面表达式的 0 个或更多搜烦V?/td>
最多一Ҏ(gu)更多
+
匚w前面表达式的臛_一个搜索项?/td>
最?0 Ҏ(gu)更多
@
匚w前面表达式的 0 个或更多搜烦,匚w可能少的字W?/td>
最一Ҏ(gu)更多
#
匚w前面表达式的一个或更多搜烦,匚w可能少的字W?/td>
重复 n ?/td>
^n
匚w前面表达式的 n 个搜索项。例如, [0-9]^4
匚wL 4 位数字的序列?/td>
字符?/td>
[]
匚w [] 内的M一个字W。要指定字符的范_请列出由短划U?(-) 分隔的v始字W和l束字符Q如 [a-z] 中所C?/td>
不在字符集中的字W?/td>
[^...]
匚w跟在 ^ 之后的不在字W集中的M字符?/td>
行首
^
匹配定位到行首?/td>
行尾
$
匹配定位到行尾?/td>
词首
<
仅当词在文本中的此位|开始时才匹配?/td>
词尾
>
仅当词在文本中的此位|结束时才匹配?/td>
分组
()
子表达式分l?/td>
?/td>
|
匚w OR W号 (|) 之前或之后的表达式?. 最常用在分l中。例如, (sponge|mud) bath
匚w“sponge bath”?#8220;mud bath”?/td>
转义W?/td>
\
匚w跟在反斜?(\) 后的字符。这使?zhn)可以查找在正则表辑ּ表示法中使用的字W,?{ ?^。例如, \^
搜烦 ^ 字符?/td>
带标记的表达?/td>
{}
标记括号内的表达式所匚w的文本?/td>
W?n 个带标记的文?/td>
\n
?#8220;查找”?#8220;替换”表达式中Q指C第 n 个带标记的表辑ּ所匚w的文本,其中 n 是从 1 ?9 的数字?
叛_齐字D?/td>
\(w,n)
?#8220;替换”表达式中Q将字段中第 n 个带标记的表辑ּ叛_齐至?w 字符宽?/td>
左对齐字D?/td>
\(-w,n)
?#8220;替换”表达式中Q将字段中第 n 个带标记的表辑ּ左对齐至?w 字符宽?/td>
止匚w
~(X)
?X 出现在表辑ּ中的此位|时止匚w。例如, real~(ity)????
匚w“realty”?#8220;really”中的“real”Q而不匚w“reality”中的“real”?/td>
字母数字字符
:a
匚w表达?
([a-zA-Z0-9])?/td>
字母字符
:c
匚w表达?br>([a-zA-Z])?/td>
十进制数
:d
匚w表达?
([0-9])?/td>
十六q制?/td>
:h
匚w表达?
([0-9a-fA-F]+)?/td>
标识W?/td>
:i
匚w表达?
([a-zA-Z_$][a-zA-Z0-9_$]*)?/td>
有理?/td>
:n
匚w表达?
(([0-9]+.[0-9]*)| ([0-9]*.[0-9]+)| ([0-9]+)).
带引L字符?/td>
:q
匚w表达?(("[^"]*")| ('[^']*'))
字母字符?/td>
:w
匚w表达?
([a-zA-Z]+)
十进制整?/td>
:z
匚w表达?
([0-9]+)?/td>
转义W?/td>
\e
Unicode U+001B?/td>
Bell
\g
Unicode U+0007?/td>
退格符
\h
Unicode U+0008?/td>
换行W?/td>
\n
匚w与^台无关的换行W。在“替换”表达式中Q插入换行符?/td>
制表W?/td>
\t
匚w制表W,Unicode U+0009?/td>
Unicode 字符
\x#### ?\u####
匚w Unicode 值给定的字符Q其?#### 是十六进制数。可以用 ISO 10646 代码Ҏ(gu)两个提供代理对的值的 Unicode 代码Ҏ(gu)定基本多语种q面Q即一个代理项Q外的字W?/td>
表达?/th>
语法
说明
大写字母
:Lu
匚wM一个大写字母。例如, :Luhe
匚w“The”但不匚w“the”?/td>
写字母
:Ll
匚wM一个小写字母。例如, :Llhe
匚w“the”但不匚w“The”?/td>
词首大写字母
:Lt
匚w大写字母和写字母l合的字W,例如QNj ?Dz?/td>
修饰W字?/td>
:Lm
匚w字母或标点符P例如逗号、交叉重音符和双撇号Q用于表C对前一字母的修饰?/td>
其他字母
:Lo
匚w其他字母Q如哥特体字?ahsa?/td>
十进制数
:Nd
匚w十进制数Q如 0-9Q和它们的双字节{效数?/td>
字母数字
:Nl
匚w字母数字Q例如罗马数字和表意数字零?/td>
其他数字
:No
匚w其他数字Q如旧斜体数字一?/td>
开始标点符?/td>
:Ps
匚w开始标点符P例如左方括号和左大括受?/td>
l束标点W号
:Pe
匚wl束标点W号Q例如右Ҏ(gu)号和叛_括号?/td>
左引?/td>
:Pi
匚w左双引号?/td>
叛_?/td>
:Pf
匚w单引号和叛_引号?
破折?/td>
:Pd
匚w破折h记?/td>
q接W号
:Pc
匚w下划U标记?/td>
其他标点W号
:Po
匚w逗号 (,)???、@???amp;?、\、冒?(:)、分?(;)? ?/?/td>
I白分隔W?/td>
:Zs
匚wI白?/td>
行分隔符
:Zl
匚w Unicode 字符 U+2028?/td>
D落分隔W?/td>
:Zp
匚w Unicode 字符 U+2029?/td>
无间隔标?/td>
:Mn
匚w无间隔标记?/td>
l合标记
:Mc
匚wl合标记?/td>
闭标记
:Me
匚w闭标记?
数学W号
:Sm
匚w +?、~、| ?lt; ?>?/td>
货币W号
:Sc
匚w $ 和其他货币符受?/td>
修饰W号
:Sk
匚w修饰W号Q如抑扬韟뀁抑音符号和镉KW号?/td>
其他W号
:So
匚w其他W号Q如版权W号、段落标记和度数W号?/td>
其他控制
:Cc
匚w行尾?/td>
其他格式
:Cf
格式化控制字W,例如双向控制字符?/td>
代理?/td>
:Cs
匚w代理对的一半?/td>
其他U用
:Co
匚wU用区域的Q何字W?/td>
其他未分配的字符
:Cn
匚w未映到 Unicode 字符的字W?/td>
表达?/th>
语法
说明
Alpha
:Al
匚wM一个字W。例如, :Alhe
匚w“The”?#8220;then”?#8220;reached”{单词?/td>
数字
:Nu
匚wM一个数或数字?/td>
标点W号
:Pu
匚wM一个标点符P??、@? {等?/td>
I白
:Wh
匚w所有类型的I格Q包括印刷和表意文字的空根{?/td>
Bidi
:Bi
匚w诸如阿拉伯文和希伯来文这cM叛_左书写的字符?/td>
朝鲜?/td>
:Ha
匚w朝鲜文和l合朝鲜文字母?/td>
q_?/td>
:Hi
匚wq_名字W?/td>
片假?/td>
:Ka
匚w片假名字W?/td>
表意文字/汉字/日文汉字
:Id
匚w表意文字字符Q如汉字和日文汉?/td>
]]>
]]>
或者组件生准的文。Doc-O-Matic使用源代码中的符号和注释以及外部的文?br>文g创徏与流行的文样式一致的文?/p>
中的cdơ结构。DocVizor快速地产生完整可供打印的类层次l构图,包括从第?br>方库中来的那些类Q除此之外DocVizorq能从类信息中生HTML文g?/p>
++代码的重构能够尽可能的有效率和简单?/p>
提出警告信息?/p>
C++的类?/p>
是再ơ编译?/p>
d了对multimethod的支持?/p>
数参数。它是一个编译器的外壟?/p>
U的开源测试框架。CppUnit ?nbsp;JUnit 一样主要思想来源于极限编E。主要功能就
是对单元试q行理Qƈ可进行自动化试?/p>
(3) Cantata++
展单元测试和集成试的需?
yplus/index.shtml
o内自动化调试q程加速开发ƈ且羃短上市的周期。BoundsChecker提供清楚Q详l?br>的程序错误分析,许多是对C++独有的ƈ且在staticQstack和heap内存中检和?br>断错误,以及发现内存和资源的泄漏。 (6) Insure++
发者提供完整的错误诊断Q和q行时性能分析工具包?/p>
误?/p>
Q直到标准的出台才正式定型,但是在标准库的实C却很令hƣ慰得看到多U实
玎ͼq且已被实践证明为有工业U别强度的佳作?/p>
其OEM的licenseQ在其C/C++的品中采用Dinkumware的库?/p>
Mpl
Thread
Python
smart_ptr
Ҏ(gu)准C++的强调,是编写^台无养ICC++的开发者必备的工具。但是Boost中也
有很多是实验性质的东西,在实际的开发中实用需要}慎。ƈ且很多Boost中的库功
能堪U对语言功能的扩展,其构造用精巧的手法Q不要N然的p旉研读。Bo
ost另外一面,比如Graphq样的库则是h工业强度Q结构良好,非常值得研读?br>_֓代码Qƈ且也可以攑ֿ的在产品代码中多多利用?/p>
发中QGUI库的选择也是非常重要的一件事情,下面我们lD一下可选择的GUI库,
各自的特点以及相兛_L支持?/p>
ws API 之上Q能够ɽE序员的工作更容?~程效率高,减少了大量在建立 Windo
ws E序时必ȝ写的代码Q同时它q提供了所有一?nbsp;C++ ~程的优点,例如l承
和封装。MFC ~写的程序在各个版本的Windows操作pȝ上是可移植的Q例如,?br>Windows 3.1下编写的代码可以很容易地UL?nbsp;Windows NT ?nbsp;Windows 95 上。但
是在最q发展以及官Ҏ(gu)持上日渐势微?/p>
很容易扩展,q且允许真正地组件编E。自?996q早些时候,Qtq入商业领域Q?br>它已l成为全世界范围内数千种成功的应用程序的基础。Qt也是行的Linux桌面?br>境KDE 的基Q同时它q支持Windows、Macintosh、Unix/X11{多U^台?/p>
器就是基于这个库的?/p>
该是什么样子的感受出发Q从而开始了对这个库的开发。有兴趣的可以尝试一下?/p>
(5) WTL
寸,以及速度优化斚w做得非常C。主要面向的使用体是开发COM轻量U供|络
下蝲的可视化控g的开发者?/p>
Communication EnvironmentQ是可以自由使用、开放源代码的面向对象框Ӟ?br>其中实现了许多用于ƈ发通信软g的核心模式。ACE提供了一l丰富的可复用C++?br>装外观(Wrapper FacadeQ和框架lgQ可跨越多种q_完成通用的通信软gd
Q其中包括:事g多\分离和事件处理器分派、信号处理、服务初始化、进E间?br>信、共享内存管理、消息\由、分布式服务动态(重)配置、ƈ发执行和同步Q等
{?/p>
tml
。XML验证在文类型定?Document Type DefinitionQDTD)斚w有很好的支持Q?br>q且?001q?2月增加了支持W3C XML Schema 的基本完整的开放标准?/p>
生相应的GUIE序来修改这个parser。在DOM和SAX两大LXML解析办法之外提供?br>另外一个可行的解决Ҏ(gu)?/p>
rQ这个xpp把这层暴露出来直接给大家使用。在要充分考虑速度的时候值得试?/p>
(4) Xalan
OM和SAX之外L一点灵感?/p>
的数值程序,?nbsp;Fortran?0%左右Q因此Blitz++正是要改掉这个缺炏V方法是?br>用C++的template技术,E序执行甚至可以比Fortran更快。Blitz++目前仍在发展?br>Q对于常见的SVDQFFTsQQMRES{常见的U性代数方法ƈ不提供,不过使用者可?br>很容易地利用Blitz++所提供的函数来构徏?/p>
象设计方便了快速的E序开发,对ƈ行机器进行了优化以达到最高的效率Q方便在
工业和研I环境中使用?/p>
矩阵的大量线性代数方面的功能。在某些应用使用高性能~译器的情况下,比如In
tel的编译器Q从产生的汇~代码可以看出其与手写几乎没有两L效能?/p>
部分重要的解x案和Ҏ(gu)以C++库的形式提供l工业和学术界的用户?/p>
B,以及S3MQ,控制接口Q键盘,鼠标和遥感)QXMS?/p>
先生Z国游戏开发事业所做出的A献?/p>
。它的目的是让开发者能更方便和直接地开发基?Dg讑֤的应用程序或游戏?br>引擎中的cdҎ(gu)底层的系l库Q如QDirect3D和OpenGLQ的全部使用l节q行?br>抽象Qƈ提供了基于现实世界对象的接口和其它类?/p>
中很隄到的大量的线E方面的功能?/p>
代码Qƈ且支持多U程环境和UnicodeQ同时还有正则表辑ּ的支持?/p>
机制Qi/opȝ包括Z插g的网l协议透明的i/o架构Q基于插件的应用E序消息
日志框架Q访问sql数据库的cȝ{?/p>
U程QUnicodeQ废料收集,I/OQ网l,实用工具QXMLQ等{)Q以及对Java, P
erl, Python, TCL, Lisp, COM ?nbsp;CORBA的集成?/p>
库来提供。同时还提供了智能指针这h较实用的功能?/p>
设施?/p>
师Peter Norvig?nbsp;“Teach Yourself Programming in Ten Years”一文中将?br>数式语言列ؓ臛_应当学习?cȝE语a之一?/p>
]]>
动态内存分配就是指在程序执行的q程中动态地分配或者回收存储空间的分配内存的方法。动态内存分配不像数l等静态内存分配方法那样需要预先分配存储空_而是ql根据程序的需要即时分配,且分配的大小是E序要求的大。本文简单介l动态内存分配函数mallocQ)及几U实现方法?/p>
1Q??/strong>
mallocQ)是C语言中动态存储管理的一l标准库函数之一。其作用是在内存的动态存储区中分配一个长度ؓsize的连l空间。其参数是一个无W号整Ş敎ͼq回值是一个指向所分配的连l存储域的v始地址的指针。还有一点必L意的是,当函数未能成功分配存储空_如内存不I׃q回一个NULL指针。所以在调用该函数时应该返回值是否ؓNULLq执行相应的操作?/p>
2Q?函数说明
C语言的动态存储管理由一l标准库函数实现Q其原型在标准文?lt;stdlib.h>里描qͼ需要用q些功能时应包含q个文g。与动态存储分配有关的函数共有四个Q其中就包括存储分配函数mallocQ)。函数原型是Qvoid *malloc (size_t n);q里的size_t是标准库里定义的一个类型,它是一个无W号整型。这个整型能够满x有对存储块大描q的需要,具体相当于哪个整型由具体的Cpȝ定。malloc的返回gؓ(void *)cdQ这是通用指针的一个重要用途)Q它分配一片能存放大小为n的数据的存储块,q回对应的指针|如果不能满甌Q找不到能满求的存储块)p回NULL。在使用Ӟ应该把malloc的返回D{换到特定指针cdQ赋l一个指针?/p>
注意Q虽然这里的存储块是通过动态分配得到的Q但是它的大也是确定的Q同样不允许界使用。例如上面程序段分配的块里能存n个双_ֺ数据Q随后的使用必dq个范围内进行。越界用动态分配的存储块,其是越界赋|可能引v非常严重的后果,通常会破坏程序的q行pȝQ可能造成本程序或者整个计机pȝ垮台?/p>
下例是一个动态分配的例子Q?br>#include <stdlib.h>
main()
{
int count,*array; /*count是一个计数器Qarray是一个整型指针,也可以理解ؓ指向一个整型数l的首地址*/
if((array(int *) malloc (10*sizeof(int)))==NULL)
{
printf("不能成功分配存储I间?);
exit(1);
}
for (count=0;count?0;count++) /*l数l赋?/
array[count]=count;
for(count=0;count?0;count++) /*打印数组元素*/
printf("%2d",array[count]);
}
上例中动态分配了10个整型存储区域,然后q行赋值ƈ打印。例中if((array(int *) malloc (10*sizeof(int)))==NULL)语句可以分ؓ以下几步Q?br> 1Q分?0个整型的q箋存储I间Qƈq回一个指向其起始地址的整型指?br> 2Q把此整型指针地址赋给array
3Q检返回值是否ؓNULL
3Q?mallocQ)工作机制
malloc函数的实质体现在Q它有一个将可用的内存块q接Z个长长的列表的所谓空闲链表。调用malloc函数Ӟ它沿q接表寻找一个大到以满用戯求所需要的内存块。然后,该内存块一分ؓ二(一块的大小与用戯求的大小相等Q另一块的大小是剩下的字节)。接下来Q将分配l用L那块内存传给用户Qƈ剩下的那块Q如果有的话Q返回到q接表上。调用free函数Ӟ它将用户释放的内存块q接到空闲链上。到最后,I闲链会被切成很多的内存片D,如果q时用户甌一个大的内存片D,那么I闲链上可能没有可以满用户要求的片D了。于是,malloc函数h延时Qƈ开始在I闲链上ȝ倒柜地检查各内存片段Q对它们q行整理Q将盔R的小I闲块合q成较大的内存块?/p>
4Q?mallocQ)在操作系l中的实?/strong>
?C E序中,多次使用malloc () ?free()。不q,(zhn)可能没有用一些时间去思考它们在(zhn)的操作pȝ中是如何实现的。本节将向?zhn)展?malloc ?free 的一个最化实现的代码Q来帮助说明理内存旉涉及C哪些事情?/p>
在大部分操作pȝ中,内存分配׃下两个简单的函数来处理:
void *malloc (long numbytes)Q该函数负责分配 numbytes 大小的内存,q返回指向第一个字节的指针?/p>
void free(void *firstbyte)Q如果给定一个由先前?malloc q回的指针,那么该函C分配的I间归还l进E的“I闲I间”?/p>
malloc_init 是初始化内存分配程序的函数。它要完成以下三件事Q将分配E序标识为已l初始化Q找到系l中最后一个有效内存地址Q然后徏立v指向我们理的内存的指针。这三个变量都是全局变量Q?/p>
清单 1. 我们的简单分配程序的全局变量
int has_initialized = 0;
void *managed_memory_start;
void *last_valid_address;
如前所qͼ被映的内存的边界(最后一个有效地址Q常被称为系l中断点或?当前中断炏V在很多 UNIX? pȝ中,Z指出当前pȝ中断点,必须使用 sbrk(0) 函数?sbrk Ҏ(gu)参数中给出的字节数移动当前系l中断点Q然后返回新的系l中断点。用参?0 只是q回当前中断炏V这里是我们?malloc 初始化代码,它将扑ֈ当前中断点ƈ初始化我们的变量Q?/p>
清单 2. 分配E序初始化函?br>/* 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;
}
现在Qؓ了完全地理内存Q我们需要能够追t要分配和回收哪些内存。在对内存块q行?free 调用之后Q我们需要做的是诸如它们标Cؓ未被使用的等事情Qƈ且,在调?malloc Ӟ我们要能够定位未被用的内存块。因此, malloc q回的每块内存的起始处首先要有这个结构:
清单 3. 内存控制块结构定?br>struct mem_control_block {
int is_available;
int size;
};
现在Q?zhn)可能会认为当E序调用 malloc 时这会引发问?—?它们如何知道q个l构Q答案是它们不必知道Q在q回指针之前Q我们会其Ud到这个结构之后,把它隐藏h。这使得q回的指针指向没有用于Q何其他用途的内存。那P从调用程序的角度来看Q它们所得到的全部是I闲的、开攄内存。然后,当通过 free() 该指针传递回来时Q我们只需要倒退几个内存字节可以再ơ找到这个结构?/p>
在讨论分配内存之前,我们先讨论释放Q因为它更简单。ؓ了释攑ֆ存,我们必须要做的惟一一件事情就是,获得我们l出的指针,回退 sizeof(struct mem_control_block) 个字节,q将其标Cؓ可用的。这里是对应的代码:
清单 4. 解除分配函数
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;
}
如?zhn)所见,在这个分配程序中Q内存的释放使用了一个非常简单的机制Q在固定旉内完成内存释放。分配内存稍微困难一些。以下是该算法的略述Q?/p>
清单 5. d配程序的伪代?br>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
我们主要使用q接的指针遍历内存来L开攄内存块。这里是代码Q?/p>
清单 6. d配程?br>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;
}
q就是我们的内存理器。现在,我们只需要构建它Qƈ在程序中使用它即可?br>
5Q?mallocQ)的其他实?/p>
malloc() 的实现有很多Q这些实现各有优点与~点。在设计一个分配程序时Q要面许多需要折L选择Q其中包括:
分配的速度?
回收的速度?
有线E的环境的行为?
内存要被用光时的行为?
局部缓存?
记QBookkeepingQ内存开销?
虚拟内存环境中的行ؓ?
的或者大的对象?
实时保证?br>每一个实现都有其自n的优~点集合。在我们的简单的分配E序中,分配非常慢,而回攉常快。另外,׃它在使用虚拟内存pȝ斚w较差Q所以它最适于处理大的对象?/p>
q有其他许多分配E序可以使用。其中包括:
Doug Lea MallocQDoug Lea Malloc 实际上是完整的一l分配程序,其中包括 Doug Lea 的原始分配程序,GNU libc 分配E序?ptmalloc?Doug Lea 的分配程序有着与我们的版本非常cM的基本结构,但是它加入了索引Q这使得搜烦速度更快Qƈ且可以将多个没有被用的块组合ؓ一个大的块。它q支持缓存,以便更快地再ơ用最q释攄内存?ptmalloc ?Doug Lea Malloc 的一个扩展版本,支持多线E。在本文后面?参考资料部分中Q有一描q?Doug Lea ?Malloc 实现的文章?/p>
BSD MallocQBSD Malloc 是随 4.2 BSD 发行的实玎ͼ包含?FreeBSD 之中Q这个分配程序可以从预先实大小的对象构成的池中分配对象。它有一些用于对象大的 size c,q些对象的大ؓ 2 的若q次q减L一常数。所以,如果(zhn)请求给定大的一个对象,它就单地分配一个与之匹配的 size cR这样就提供了一个快速的实现Q但是可能会费内存。在 参考资料部分中Q有一描q该实现的文章?/p>
HoardQ编?Hoard 的目标是使内存分配在多线E环境中q行得非常快。因此,它的构造以锁的使用Z心,从而所有进E不必等待分配内存。它可以显著地加快那些进行很多分配和回收的多U程q程的速度。在 参考资料部分中Q有一描q该实现的文章?br>众多可用的分配程序中最有名的就是上q这些分配程序。如果?zhn)的程序有特别的分配需求,那么(zhn)可能更愿意~写一个定制的能匹配?zhn)的程序内存分配方式的分配E序。不q,如果不熟(zhn)分配程序的设计Q那么定制分配程序通常会带来比它们解决的问题更多的问题?/p>
6Q?l束?/strong>
前面已经提过Q多ơ调用mallocQ)后空闲内存被切成很多的小内存片段Q这׃得用户在甌内存使用Ӟ׃找不到够大的内存空_mallocQ)需要进行内存整理,使得函数的性能来低。聪明的E序员通过L分配大小?的幂的内存块Q而最大限度地降低潜在的malloc性能丧失。也是_所分配的内存块大小?字节?字节?6字节?8446744073709551616字节Q等{。这样做最大限度地减少了进入空闲链的怪异片段Q各U尺寸的片D都有)的数量。尽看hq好像浪费了I间Q但也容易看出浪费的I间永远不会过50%?/p>
参考文献:
[1] Jonathan BartlettQ内存管理内q? developerWorks 中国Q?004q?1?/p>
如果容器是vector、string或dequeQ用erase-remove惯用法?/p>
如果容器是listQ用list::remove?/p>
如果容器是标准关联容器,使用它的erase成员函数?/p>
如果容器是vector、string或dequeQ用erase-remove_if惯用法?/p>
如果容器是listQ用list::remove_if?/p>
如果容器是标准关联容器,使用remove_copy_if和swapQ或写一个@环来遍历容器元素Q当你把q代器传lerase时记得后|递增它?/p>
如果容器是标准序列容器,写一个@环来遍历容器元素Q每当调用erase时记得都用它的返回值更C的P代器?/p>
如果容器是标准关联容器,写一个@环来遍历容器元素Q当你把q代器传lerase时记得后|递增它?/p>