??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲综合精品香蕉久久网97,人妻无码精品久久亚瑟影视 ,色偷偷88欧美精品久久久http://www.shnenglu.com/jianlinzhang/zh-cnWed, 07 May 2025 18:12:02 GMTWed, 07 May 2025 18:12:02 GMT60关于 boost ?VA 的一些见?/title><link>http://www.shnenglu.com/jianlinzhang/archive/2009/10/21/99091.html</link><dc:creator>张徏?/dc:creator><author>张徏?/author><pubDate>Wed, 21 Oct 2009 02:31:00 GMT</pubDate><guid>http://www.shnenglu.com/jianlinzhang/archive/2009/10/21/99091.html</guid><wfw:comment>http://www.shnenglu.com/jianlinzhang/comments/99091.html</wfw:comment><comments>http://www.shnenglu.com/jianlinzhang/archive/2009/10/21/99091.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.shnenglu.com/jianlinzhang/comments/commentRss/99091.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jianlinzhang/services/trackbacks/99091.html</trackback:ping><description><![CDATA[        最q一D|间安装了boostQ但是由于以前无q方面的l验Q导致了在安装完boost后,q用到vs2005或者vs2008Ӟvisual assist 会不停的解析boostQ导致我的虚拟内存会不断增加Q最后死机或者vs崩溃Q开始还以ؓ自己在编译boost库时出现了问题,因此l箋上网L关于q方面的问题Q时至今日才发现|络也ƈ非万能,或者可能我的问题大安没遇到过QMQ该问题我一直没有解冻I只好忍痛割爱Q将va的设|中不添加boost一V尽关于boost的程序编译,q行都没有问题,但在~少了va的强力支撑下Q编写boostE序的相当的J琐。。?br>        今天Q我l于发现了其中的~由Q原来是因ؓ我的boost目录中包含的有中文字W串。。。哎Q没惛_啊。在重新讄了boost的目录后Q一切就ok了。。?br>        希望q对于有些同行来说有点用处。。。O(∩_∩)O哈哈~ <img src ="http://www.shnenglu.com/jianlinzhang/aggbug/99091.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jianlinzhang/" target="_blank">张徏?/a> 2009-10-21 10:31 <a href="http://www.shnenglu.com/jianlinzhang/archive/2009/10/21/99091.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>堆和栈的区别http://www.shnenglu.com/jianlinzhang/archive/2009/10/14/98545.html张徏?/dc:creator>张徏?/author>Wed, 14 Oct 2009 01:35:00 GMThttp://www.shnenglu.com/jianlinzhang/archive/2009/10/14/98545.htmlhttp://www.shnenglu.com/jianlinzhang/comments/98545.htmlhttp://www.shnenglu.com/jianlinzhang/archive/2009/10/14/98545.html#Feedback1http://www.shnenglu.com/jianlinzhang/comments/commentRss/98545.htmlhttp://www.shnenglu.com/jianlinzhang/services/trackbacks/98545.html 1 堆和栈的区别 (转脓)
堆和栈的区别 (转脓) 
非本Z?因非常经?所以收归旗?与众人阅?原作者不?

堆和栈的区别
一、预备知识—程序的内存分配
一个由c/C++~译的程序占用的内存分ؓ以下几个部分
1、栈区(stackQ?nbsp;q译器自动分配释放 Q存攑և数的参数|局部变量的值等。其操作方式cM于数据结构中的栈?
2、堆区(heapQ?nbsp;?nbsp;一般由E序员分配释放, 若程序员不释放,E序l束时可能由OS回收 。注意它与数据结构中的堆是两回事Q分配方式倒是cM于链表,呵呵?
3、全局区(静态区Q(staticQ—,全局变量和静态变量的存储是放在一块的Q初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在盔R的另一块区域?nbsp;- E序l束后有pȝ释放 
4、文字常量区—常量字W串是攑֜q里的?nbsp;E序l束后由pȝ释放
5、程序代码区—存攑ևC的二q制代码?
二、例子程?nbsp;
q是一个前辈写的,非常详细 
//main.cpp 
int a = 0; 全局初始化区 
char *p1; 全局未初始化?nbsp;
main() 

int b; ?nbsp;
char s[] = "abc"; ?nbsp;
char *p2; ?nbsp;
char *p3 = "123456"; 123456\0在常量区Qp3在栈上?nbsp;
static int c =0Q?nbsp;全局Q静态)初始化区 
p1 = (char *)malloc(10); 
p2 = (char *)malloc(20); 
分配得来?0?0字节的区域就在堆区?nbsp;
strcpy(p1, "123456"); 123456\0攑֜帔R区,~译器可能会它与p3所指向?123456"优化成一个地斏V?nbsp;

 


二、堆和栈的理论知?nbsp;
2.1甌方式 
stack: 
ql自动分配?nbsp;例如Q声明在函数中一个局部变?nbsp;int b; pȝ自动在栈中ؓb开辟空?nbsp;
heap: 
需要程序员自己甌Qƈ指明大小Q在c中malloc函数 
如p1 = (char *)malloc(10); 
在C++中用newq算W?nbsp;
如p2 = (char *)malloc(10); 
但是注意p1、p2本n是在栈中的?nbsp;


2.2 
甌后系l的响应 
栈:只要栈的剩余I间大于所甌I间Q系l将为程序提供内存,否则报异常提示栈溢出?nbsp;
堆:首先应该知道操作pȝ有一个记录空闲内存地址的链表,当系l收到程序的甌Ӟ 
会遍历该链表Q寻扄一个空间大于所甌I间的堆l点Q然后将该结点从I闲l点链表中删除,q将该结点的I间分配l程序,另外Q对于大多数pȝQ会在这块内存空间中的首地址处记录本ơ分配的大小Q这P代码中的delete语句才能正确的释放本内存I间。另外,׃扑ֈ的堆l点的大不一定正好等于申L大小Q系l会自动的将多余的那部分重新攑օI闲链表中?nbsp;

2.3甌大小的限?nbsp;
栈:在Windows?栈是向低地址扩展的数据结构,是一块连l的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是pȝ预先规定好的Q在WINDOWS下,栈的大小?MQ也有的说是1MQM是一个编译时q定的常数Q,如果甌的空间超q栈的剩余空间时Q将提示overflow。因此,能从栈获得的I间较小?nbsp;
堆:堆是向高地址扩展的数据结构,是不q箋的内存区域。这是由于系l是用链表来存储的空闲内存地址的,自然是不q箋的,而链表的遍历方向是由低地址向高地址。堆的大受限于计算机系l中有效的虚拟内存。由此可见,堆获得的I间比较灉|Q也比较大?nbsp;


2.4甌效率的比较: 
栈由pȝ自动分配Q速度较快。但E序员是无法控制的?nbsp;
堆是由new分配的内存,一般速度比较慢,而且Ҏ产生内存片,不过用v来最方便. 
另外Q在WINDOWS下,最好的方式是用VirtualAlloc分配内存Q他不是在堆Q也不是在栈是直接在q程的地址I间中保留一快内存,虽然用v来最不方ѝ但是速度快,也最灉|?nbsp;

2.5堆和栈中的存储内?nbsp;
栈: 在函数调用时Q第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句Q的地址Q然后是函数的各个参敎ͼ在大多数的C~译器中Q参数是由右往左入栈的Q然后是函数中的局部变量。注意静态变量是不入栈的?nbsp;
作者:121.30.67.*
2006-11-26 23:15 回复此发a 

2 堆和栈的区别 (转脓)
当本ơ函数调用结束后Q局部变量先出栈Q然后是参数Q最后栈指针指向最开始存的地址Q也是dC的下一条指令,E序p点l运行?nbsp;
堆:一般是在堆的头部用一个字节存攑֠的大。堆中的具体内容有程序员安排?nbsp;

2.6存取效率的比?nbsp;

char s1[] = "aaaaaaaaaaaaaaa"; 
char *s2 = "bbbbbbbbbbbbbbbbb"; 
aaaaaaaaaaa是在q行时刻赋值的Q?nbsp;
而bbbbbbbbbbb是在~译时就定的; 
但是Q在以后的存取中Q在栈上的数l比指针所指向的字W串(例如?快?nbsp;
比如Q?nbsp;
#include 
void main() 

char a = 1; 
char c[] = "1234567890"; 
char *p ="1234567890"; 
a = c[1]; 
a = p[1]; 
return; 

对应的汇~代?nbsp;
10: a = c[1]; 
00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh] 
0040106A 88 4D FC mov byte ptr [ebp-4],cl 
11: a = p[1]; 
0040106D 8B 55 EC mov edx,dword ptr [ebp-14h] 
00401070 8A 42 01 mov al,byte ptr [edx+1] 
00401073 88 45 FC mov byte ptr [ebp-4],al 
W一U在d时直接就把字W串中的元素d寄存器cl中,而第二种则要先把指针D到edx中,在根据edxd字符Q显然慢了?nbsp;


2.7结Q?nbsp;
堆和栈的区别可以用如下的比喻来看出: 
使用栈就象我们去饭馆里吃饭,只管点菜Q发出申P、付钱、和吃(使用Q,吃饱了就赎ͼ不必理会切菜、洗菜等准备工作和洗、刷锅等扫尾工作Q他的好处是快捷Q但是自由度?nbsp;
使用堆就象是自己动手做喜Ƣ吃的菜_比较ȝQ但是比较符合自q口味Q而且自由度大?nbsp;





windowsq程中的内存l构


在阅L文之前,如果你连堆栈是什么多不知道的话,请先阅读文章后面的基知识?nbsp;

接触q编E的人都知道Q高U语a都能通过变量名来讉K内存中的数据。那么这些变量在内存中是如何存放的呢Q程序又是如何用这些变量的呢?下面׃Ҏq行深入的讨论。下文中的C语言代码如没有特别声明,默认都用VC~译的release版?nbsp;

首先Q来了解一?nbsp;C 语言的变量是如何在内存分部的。C 语言有全局变量(Global)、本地变?Local)Q静态变?Static)、寄存器变量(Regeister)。每U变量都有不同的分配方式。先来看下面q段代码Q?nbsp;

#include <stdio.h> 

int g1=0, g2=0, g3=0; 

int main() 

static int s1=0, s2=0, s3=0; 
int v1=0, v2=0, v3=0; 

//打印出各个变量的内存地址 

printf("0x%08x\n",&v1); //打印各本地变量的内存地址 
printf("0x%08x\n",&v2); 
printf("0x%08x\n\n",&v3); 
printf("0x%08x\n",&g1); //打印各全局变量的内存地址 
printf("0x%08x\n",&g2); 
printf("0x%08x\n\n",&g3); 
printf("0x%08x\n",&s1); //打印各静态变量的内存地址 
printf("0x%08x\n",&s2); 
printf("0x%08x\n\n",&s3); 
return 0; 


~译后的执行l果是: 

0x0012ff78 
0x0012ff7c 
0x0012ff80 

0x004068d0 
0x004068d4 
0x004068d8 

0x004068dc 
0x004068e0 
0x004068e4 

输出的结果就是变量的内存地址。其中v1,v2,v3是本地变量,g1,g2,g3是全局变量Qs1,s2,s3是静态变量。你可以看到q些变量在内存是q箋分布的,但是本地变量和全局变量分配的内存地址差了十万八千里,而全局变量和静态变量分配的内存是连l的。这是因为本地变量和全局/静态变量是分配在不同类型的内存区域中的l果。对于一个进E的内存I间而言Q可以在逻辑上分?个部份:代码区,静态数据区和动态数据区。动态数据区一般就?#8220;堆栈”?#8220;?stack)”?#8220;?heap)”是两U不同的动态数据区Q栈是一U线性结构,堆是一U链式结构。进E的每个U程都有U有?#8220;?#8221;Q所以每个线E虽然代码一P但本地变量的数据都是互不q扰。一个堆栈可以通过“基地址”?#8220;栈顶”地址来描q。全局变量和静态变量分配在静态数据区Q本地变量分配在动态数据区Q即堆栈中。程序通过堆栈的基地址和偏U量来访问本地变量?nbsp;
作者:121.30.67.*
2006-11-26 23:15 回复此发a 

3 堆和栈的区别 (转脓)


├———————┤低端内存区域 
?nbsp;…… ?nbsp;
├———————┤ 
?nbsp;动态数据区 ?nbsp;
├———————┤ 
?nbsp;…… ?nbsp;
├———————┤ 
?nbsp;代码?nbsp;?nbsp;
├———————┤ 
?nbsp;静态数据区 ?nbsp;
├———————┤ 
?nbsp;…… ?nbsp;
├———————┤高端内存区域 


堆栈是一个先q后出的数据l构Q栈地址L于{于栈的基地址。我们可以先了解一下函数调用的q程Q以便对堆栈在程序中的作用有更深入的了解。不同的语言有不同的函数调用规定Q这些因素有参数的压入规则和堆栈的^衡。windows API的调用规则和ANSI C的函数调用规则是不一LQ前者由被调函数调整堆栈Q后者由调用者调整堆栈。两者通过“__stdcall”?#8220;__cdecl”前缀区分。先看下面这D代码: 

#include <stdio.h> 

void __stdcall func(int param1,int param2,int param3) 

int var1=param1; 
int var2=param2; 
int var3=param3; 
printf("0x%08x\n",¶m1); //打印出各个变量的内存地址 
printf("0x%08x\n",¶m2); 
printf("0x%08x\n\n",¶m3); 
printf("0x%08x\n",&var1); 
printf("0x%08x\n",&var2); 
printf("0x%08x\n\n",&var3); 
return; 


int main() 

func(1,2,3); 
return 0; 


~译后的执行l果是: 

0x0012ff78 
0x0012ff7c 
0x0012ff80 

0x0012ff68 
0x0012ff6c 
0x0012ff70 


├———————┤<—函数执行时的栈ӞESPQ、低端内存区?nbsp;
?nbsp;…… ?nbsp;
├———————┤ 
?nbsp;var 1 ?nbsp;
├———————┤ 
?nbsp;var 2 ?nbsp;
├———————┤ 
?nbsp;var 3 ?nbsp;
├———————┤ 
?nbsp;RET ?nbsp;
├———————┤<?#8220;__cdecl”函数q回后的栈顶QESPQ?nbsp;
?nbsp;parameter 1 ?nbsp;
├———————┤ 
?nbsp;parameter 2 ?nbsp;
├———————┤ 
?nbsp;parameter 3 ?nbsp;
├———————┤<?#8220;__stdcall”函数q回后的栈顶QESPQ?nbsp;
?nbsp;…… ?nbsp;
├———————┤<—栈底(基地址 EBPQ、高端内存区?nbsp;


上图是函数调用q程中堆栈的样子了。首先,三个参数以从又到左的ơ序压入堆栈Q先?#8220;param3”Q再?#8220;param2”Q最后压?#8220;param1”Q然后压入函数的q回地址(RET)Q接着跌{到函数地址接着执行Q这里要补充一点,介绍UNIX下的~冲溢出原理的文章中都提到在压入RET后,l箋压入当前EBPQ然后用当前ESP代替EBP。然而,有一介lwindows下函数调用的文章中说Q在windows下的函数调用也有q一步骤Q但Ҏ我的实际调试Qƈ未发现这一步,q还可以从param3和var1之间只有4字节的间隙这点看出来Q;W三步,栈?ESP)减去一个数Qؓ本地变量分配内存I间Q上例中是减?2字节(ESP=ESP-3*4Q每个int变量占用4个字?Q接着初始化本地变量的内存空间。由?#8220;__stdcall”调用p调函数调整堆栈,所以在函数q回前要恢复堆栈Q先回收本地变量占用的内?ESP=ESP+3*4)Q然后取回地址Q填入EIP寄存器,回收先前压入参数占用的内?ESP=ESP+3*4)Ql执行调用者的代码。参见下列汇~代码: 

;--------------func 函数的汇~代?------------------ 

:00401000 83EC0C sub esp, 0000000C //创徏本地变量的内存空?nbsp;
:00401003 8B442410 mov eax, dword ptr [esp+10] 
:00401007 8B4C2414 mov ecx, dword ptr [esp+14] 
:0040100B 8B542418 mov edx, dword ptr [esp+18] 
:0040100F 89442400 mov dword ptr [esp], eax 
:00401013 8D442410 lea eax, dword ptr [esp+10] 
:00401017 894C2404 mov dword ptr [esp+04], ecx 

……………………Q省略若q代码) 

:00401075 83C43C add esp, 0000003C ;恢复堆栈Q回收本地变量的内存I间 
:00401078 C3 ret 000C ;函数q回Q恢复参数占用的内存I间 
作者:121.30.67.*
2006-11-26 23:15 回复此发a 

4 堆和栈的区别 (转脓)
;如果?#8220;__cdecl”的话Q这里是“ret”Q堆栈将p用者恢?nbsp;

;-------------------函数l束------------------------- 


;--------------ȝ序调用func函数的代?------------- 

:00401080 6A03 push 00000003 //压入参数param3 
:00401082 6A02 push 00000002 //压入参数param2 
:00401084 6A01 push 00000001 //压入参数param1 
:00401086 E875FFFFFF call 00401000 //调用func函数 
;如果?#8220;__cdecl”的话Q将在这里恢复堆栈,“add esp, 0000000C” 

聪明的读者看到这里,差不多就明白~冲溢出的原理了。先来看下面的代码: 

#include <stdio.h> 
#include <string.h> 

void __stdcall func() 

char lpBuff[8]="\0"; 
strcat(lpBuff,"AAAAAAAAAAA"); 
return; 


int main() 

func(); 
return 0; 


~译后执行一下回怎么P哈,“"0x00414141"指o引用?0x00000000"内存。该内存不能?read"?#8221;Q?#8220;非法操作”喽!"41"是"A"?6q制的ASCII码了Q那明显是strcatq句出的问题了?lpBuff"的大只?字节Q算q结\0Q那strcat最多只能写??A"Q但E序实际写入?1?A"外加1个\0。再来看看上面那q图Q多出来?个字节正好覆盖了RET的所在的内存I间Q导致函数返回到一个错误的内存地址Q执行了错误的指令。如果能_ֿ构造这个字W串Q它分成三部分Q前一部䆾仅仅是填充的无意义数据以辑ֈ溢出的目的,接着是一个覆盖RET的数据,紧接着是一DshellcodeQ那只要着个RET地址能指向这Dshellcode的第一个指令,那函数返回时p执行shellcode了。但是Y件的不同版本和不同的q行环境都可能媄响这Dshellcode在内存中的位|,那么要构造这个RET是十分困隄。一般都在RET和shellcode之间填充大量的NOP指oQ得exploit有更强的通用性?nbsp;


├———————┤<—低端内存区?nbsp;
?nbsp;…… ?nbsp;
├———————┤<—由exploit填入数据的开?nbsp;
?nbsp;?nbsp;
?nbsp;buffer ?lt;—填入无用的数据 
?nbsp;?nbsp;
├———————┤ 
?nbsp;RET ?lt;—指向shellcodeQ或NOP指o的范?nbsp;
├———————┤ 
?nbsp;NOP ?nbsp;
?nbsp;…… ?lt;—填入的NOP指oQ是RET可指向的范围 
?nbsp;NOP ?nbsp;
├———————┤ 
?nbsp;?nbsp;
?nbsp;shellcode ?nbsp;
?nbsp;?nbsp;
├———————┤<—由exploit填入数据的结?nbsp;
?nbsp;…… ?nbsp;
├———————┤<—高端内存区?nbsp;


windows下的动态数据除了可存放在栈中,q可以存攑֜堆中。了解C++的朋友都知道QC++可以使用new关键字来动态分配内存。来看下面的C++代码Q?nbsp;

#include <stdio.h> 
#include <iostream.h> 
#include <windows.h> 

void func() 

char *buffer=new char[128]; 
char bufflocal[128]; 
static char buffstatic[128]; 
printf("0x%08x\n",buffer); //打印堆中变量的内存地址 
printf("0x%08x\n",bufflocal); //打印本地变量的内存地址 
printf("0x%08x\n",buffstatic); //打印静态变量的内存地址 


void main() 

func(); 
return; 


E序执行l果为: 

0x004107d0 
0x0012ff04 
0x004068c0 

可以发现用new关键字分配的内存即不在栈中,也不在静态数据区。VC~译器是通过windows下的“?heap)”来实现new关键字的内存动态分配。在?#8220;?#8221;之前Q先来了解一下和“?#8221;有关的几个API函数Q?nbsp;

HeapAlloc 在堆中申请内存空?nbsp;
HeapCreate 创徏一个新的堆对象 
HeapDestroy 销毁一个堆对象 
HeapFree 释放甌的内?nbsp;
HeapWalk 枚D堆对象的所有内存块 
GetProcessHeap 取得q程的默认堆对象 
GetProcessHeaps 取得q程所有的堆对?nbsp;
LocalAlloc 
GlobalAlloc 

当进E初始化Ӟpȝ会自动ؓq程创徏一个默认堆Q这个堆默认所占内存的大小?M。堆对象ql进行管理,它在内存中以铑ּl构存在。通过下面的代码可以通过堆动态申请内存空_ 
作者:121.30.67.*
2006-11-26 23:15 回复此发a 

5 堆和栈的区别 (转脓)

HANDLE hHeap=GetProcessHeap(); 
char *buff=HeapAlloc(hHeap,0,8); 

其中hHeap是堆对象的句柄,buff是指向申L内存I间的地址。那q个hHeapI竟是什么呢Q它的值有什么意义吗Q看看下面这D代码吧Q?nbsp;

#pragma comment(linker,"/entry:main") //定义E序的入?nbsp;
#include <windows.h> 

_CRTIMP int (__cdecl *printf)(const char *, ...); //定义STL函数printf 
/*--------------------------------------------------------------------------- 
写到q里Q我们顺便来复习一下前面所讲的知识Q?nbsp;
(*?printf函数是C语言的标准函数库中函敎ͼVC的标准函数库由msvcrt.dll模块实现?nbsp;
由函数定义可见,printf的参C数是可变的,函数内部无法预先知道调用者压入的参数个数Q函数只能通过分析W一个参数字W串的格式来获得压入参数的信息,׃q里参数的个数是动态的Q所以必ȝ调用者来q堆栈Q这里便使用了__cdecl调用规则。BTWQWindowspȝ的API函数基本上是__stdcall调用形式Q只有一个API例外Q那是wsprintfQ它使用__cdecl调用规则Q同printf函数一Pq是׃它的参数个数是可变的~故?nbsp;
---------------------------------------------------------------------------*/ 
void main() 

HANDLE hHeap=GetProcessHeap(); 
char *buff=HeapAlloc(hHeap,0,0x10); 
char *buff2=HeapAlloc(hHeap,0,0x10); 
HMODULE hMsvcrt=LoadLibrary("msvcrt.dll"); 
printf=(void *)GetProcAddress(hMsvcrt,"printf"); 
printf("0x%08x\n",hHeap); 
printf("0x%08x\n",buff); 
printf("0x%08x\n\n",buff2); 


执行l果为: 

0x00130000 
0x00133100 
0x00133118 

hHeap的值怎么和那个buff的值那么接q呢Q其实hHeapq个句柄是指向HEAP首部的地址。在q程的用户区存着一个叫PEB(q程环境?的结构,q个l构中存攄一些有兌E的重要信息Q其中在PEB首地址偏移0x18处存攄ProcessHeap是q程默认堆的地址Q而偏U?x90处存放了指向q程所有堆的地址列表的指针。windows有很多API都用进E的默认堆来存放动态数据,如windows 2000下的所有ANSI版本的函数都是在默认堆中甌内存来{换ANSI字符串到Unicode字符串的。对一个堆的访问是序q行的,同一时刻只能有一个线E访问堆中的数据Q当多个U程同时有访问要求时Q只能排队等待,q样侉K成E序执行效率下降?nbsp;

最后来说说内存中的数据寚w。所位数据对齐,是指数据所在的内存地址必须是该数据长度的整数倍,DWORD数据的内存v始地址能被4除尽QWORD数据的内存v始地址能被2除尽Qx86 CPU能直接访问对齐的数据Q当他试图访问一个未寚w的数据时Q会在内部进行一pd的调_q些调整对于E序来说是透明的,但是会降低运行速度Q所以编译器在编译程序时会尽量保证数据对齐。同样一D代码,我们来看看用VC、Dev-C++和lcc三个不同~译器编译出来的E序的执行结果: 

#include <stdio.h> 

int main() 

int a; 
char b; 
int c; 
printf("0x%08x\n",&a); 
printf("0x%08x\n",&b); 
printf("0x%08x\n",&c); 
return 0; 


q是用VC~译后的执行l果Q?nbsp;
0x0012ff7c 
0x0012ff7b 
0x0012ff80 
变量在内存中的顺序:b(1字节)-a(4字节)-c(4字节)?nbsp;

q是用Dev-C++~译后的执行l果Q?nbsp;
0x0022ff7c 
0x0022ff7b 
0x0022ff74 
变量在内存中的顺序:c(4字节)-中间盔R3字节-b(?字节)-a(4字节)?nbsp;

q是用lcc~译后的执行l果Q?nbsp;
0x0012ff6c 
0x0012ff6b 
0x0012ff64 
变量在内存中的顺序:同上?nbsp;

三个~译器都做到了数据对齐,但是后两个编译器昄没VC“聪明”Q让一个char占了4字节Q浪费内存哦?nbsp;


基础知识Q?nbsp;
堆栈是一U简单的数据l构Q是一U只允许在其一端进行插入或删除的线性表。允许插入或删除操作的一端称为栈Ӟ另一端称为栈底,对堆栈的插入和删除操作被UCؓ入栈和出栈。有一lCPU指o可以实现对进E的内存实现堆栈讉K。其中,POP指o实现出栈操作QPUSH指o实现入栈操作。CPU的ESP寄存器存攑ֽ前线E的栈顶指针QEBP寄存器中保存当前U程的栈底指针。CPU的EIP寄存器存放下一个CPU指o存放的内存地址Q当CPU执行完当前的指o后,从EIP寄存器中d下一条指令的内存地址Q然后l执行?nbsp;
作者:121.30.67.*
2006-11-26 23:15 回复此发a 

6 堆和栈的区别 (转脓)


参考:《Windows下的HEAP溢出及其利用》by: isno 
《windows核心~程》by: Jeffrey Richter 





摘要Q?nbsp;讨论常见的堆性能问题以及如何防范它们。(?nbsp;9 )

前言
您是否是动态分配的 C/C++ 对象忠实且幸q的用户Q您是否在模块间的往q通信中频J地使用?#8220;自动?#8221;Q您的程序是否因堆分配而运行v来很慢?不仅仅您遇到q样的问题。几乎所有项目迟早都会遇到堆问题。大安惌Q?#8220;我的代码真正好,只是堆太?#8221;。那只是部分正确。更深入理解堆及其用法、以及会发生什么问题,是很有用的?

什么是堆?
Q如果您已经知道什么是堆,可以跛_“什么是常见的堆性能问题Q?#8221;部分Q?

在程序中Q用堆来动态分配和释放对象。在下列情况下,调用堆操作: 

事先不知道程序所需对象的数量和大小?


对象太大而不适合堆栈分配E序?
堆用了在运行时分配l代码和堆栈的内存之外的部分内存。下囄Z堆分配程序的不同层?


GlobalAlloc/GlobalFreeQMicrosoft Win32 堆调用,q些调用直接与每个进E的默认堆进行对话?

LocalAlloc/LocalFreeQWin32 堆调用(Z?nbsp;Microsoft Windows NT 兼容Q,q些调用直接与每个进E的默认堆进行对话?

COM ?nbsp;IMalloc 分配E序Q或 CoTaskMemAlloc / CoTaskMemFreeQ:函数使用每个q程的默认堆。自动化E序使用“lg对象模型 (COM)”的分配程序,而申LE序使用每个q程堆?

C/C++ q行?nbsp;(CRT) 分配E序Q提供了 malloc() ?nbsp;free() 以及 new ?nbsp;delete 操作W。如 Microsoft Visual Basic ?nbsp;Java {语a也提供了新的操作Wƈ使用垃圾攉来代替堆。CRT 创徏自己的私有堆Q驻留在 Win32 堆的剙?

Windows NT 中,Win32 堆是 Windows NT q行时分配程序周围的薄层。所?nbsp;API 转发它们的请求给 NTDLL?

Windows NT q行时分配程序提?nbsp;Windows NT 内的核心堆分配程序。它由具?nbsp;128 个大从 8 ?nbsp;1,024 字节的空闲列表的前端分配E序l成。后端分配程序用虚拟内存来保留和提交页?

在图表的底部?#8220;虚拟内存分配E序”Q操作系l用它来保留和提交c所有分配程序用虚拟内存进行数据的存取?

分配和释攑֝不就那么单吗Qؓ何花费这么长旉Q?

堆实现的注意事项
传统上,操作pȝ和运行时库是与堆的实现共存的。在一个进E的开始,操作pȝ创徏一个默认堆Q叫?#8220;q程?#8221;。如果没有其他堆可用,则块的分配?#8220;q程?#8221;。语aq行时也能在q程内创建单独的堆。(例如QC q行时创建它自己的堆。)除这些专用的堆外Q应用程序或许多已蝲入的动态链接库 (DLL) 之一可以创徏和用单独的堆。Win32 提供一整套 API 来创建和使用U有堆。有兛_函数Q英文)的详指|请参?nbsp;MSDN?

当应用程序或 DLL 创徏U有堆时Q这些堆存在于进E空_q且在进E内是可讉K的。从l定堆分配的数据在同一个堆上释放。(不能从一个堆分配而在另一个堆释放。)

在所有虚拟内存系l中Q堆ȝ在操作系l的“虚拟内存理?#8221;的顶部。语aq行时堆也驻留在虚拟内存剙。某些情况下Q这些堆是操作系l堆中的层,而语aq行时堆则通过大块的分配来执行自己的内存管理。不使用操作pȝ堆,而用虚拟内存函数更利于堆的分配和块的用?

典型的堆实现由前、后端分配程序组成。前端分配程序维持固定大块的空闲列表。对于一ơ分配调用,堆尝试从前端列表扑ֈ一个自由块。如果失败,堆被q从后端Q保留和提交虚拟内存Q分配一个大块来满h。通用的实现有每块分配的开销Q这耗费执行周期Q也减少了可使用的存储空间?

Knowledge Base 文章 Q10758Q?#8220;?nbsp;calloc() ?nbsp;malloc() 理内存” Q搜索文章编P, 包含了有兌些主题的更多背景知识。另外,有关堆实现和设计的详l讨Z可在下列著作中找刎ͼ“Dynamic Storage Allocation: A Survey and Critical Review”Q作?nbsp;Paul R. Wilson、Mark S. Johnstone、Michael Neely ?nbsp;David BolesQ?#8220;International Workshop on Memory Management”, 作?nbsp;Kinross, Scotland, UK, 1995 q?nbsp;9 ?http://www.cs.utexas.edu/users/oops/papers.html)Q英文)?
作者:121.30.67.*
2006-11-26 23:15 回复此发a 

7 堆和栈的区别 (转脓)

Windows NT 的实玎ͼWindows NT 版本 4.0 和更新版本) 使用?nbsp;127 个大从 8 ?nbsp;1,024 字节?nbsp;8 字节寚w块空闲列表和一?#8220;大块”列表?#8220;大块”列表Q空闲列表[0]Q?nbsp;保存大于 1,024 字节的块。空闲列表容U了用双向链表链接在一L对象。默认情况下Q?#8220;q程?#8221;执行攉操作。(攉是将盔RI闲块合q成一个大块的操作。)攉耗费了额外的周期Q但减少了堆块的内部片?

单一全局锁保护堆Q防止多U程式的使用。(请参?#8220;Server Performance and Scalability Killers”中的W一个注意事? George Reilly 所著,?nbsp;“MSDN Online Web Workshop”上(站点Q?a target=_blank>http://msdn.microsoft.com/workshop/server/iis/tencom.aspQ英文)。)单一全局锁本质上是用来保护堆数据l构Q防止跨多线E的随机存取。若堆操作太频繁Q单一全局锁会Ҏ能有不利的影响?

什么是常见的堆性能问题Q?
以下是您使用堆时会遇到的最常见问题Q?nbsp;

分配操作造成的速度减慢。光分配p费很长旉。最可能Dq行速度减慢原因是空闲列表没有块Q所以运行时分配E序代码会耗费周期L较大的空闲块Q或从后端分配程序分配新块?


释放操作造成的速度减慢。释放操作耗费较多周期Q主要是启用了收集操作。收集期_每个释放操作“查找”它的盔R块,取出它们q构造成较大块,然后再把此较大块插入I闲列表。在查找期间Q内存可能会随机到Q从而导致高速缓存不能命中,性能降低?


堆竞争造成的速度减慢。当两个或多个线E同时访问数据,而且一个线El进行之前必ȝ待另一个线E完成时发生竞争。竞争LDȝQ这也是目前多处理器pȝ遇到的最大问题。当大量使用内存块的应用E序?nbsp;DLL 以多U程方式q行Q或q行于多处理器系l上Q时导致速度减慢。单一锁定的用—常用的解决Ҏ—意味着使用堆的所有操作是序列化的。当{待锁定时序列化会引LE切换上下文。可以想象交叉\口闪烁的U灯处走走停停导致的速度减慢?nbsp;
竞争通常会导致线E和q程的上下文切换。上下文切换的开销是很大的Q但开销更大的是数据从处理器高速缓存中丢失Q以及后来线E复zL的数据重建?

堆破坏造成的速度减慢。造成堆破坏的原因是应用程序对堆块的不正确使用。通常情Ş包括释放已释攄堆块或用已释放的堆块,以及块的界重写{明N题。(破坏不在本文讨论范围之内。有兛_存重写和泄漏{其他细节,请参?nbsp;Microsoft Visual C++(R) 调试文档 。)


频繁的分配和重分配造成的速度减慢。这是用脚本语a旉常普遍的现象。如字符串被反复分配Q随重分配增长和释放。不要这样做Q如果可能,量分配大字W串和用缓冲区。另一U方法就是尽量少用连接操作?
竞争是在分配和释放操作中D速度减慢的问题。理x况下Q希望用没有竞争和快速分?释放的堆。可惜,现在q没有这L通用堆,也许来会有?

在所有的服务器系l中Q如 IIS、MSProxy、DatabaseStacks、网l服务器?nbsp;Exchange 和其他), 堆锁定实在是个大瓉。处理器数越多,竞争p会恶化?

量减少堆的使用
现在您明白用堆时存在的问题了,N您不x有能解决q些问题的超U魔吗Q我可希望有。但没有法能堆运行加快—因此不要期望在产品之前的最后一星期能够大ؓ改观。如果提前规划堆{略Q情况将会大大好转。调整用堆的方法,减少对堆的操作是提高性能的良斏V?

如何减少使用堆操作?通过利用数据l构内的位置可减堆操作的次数。请考虑下列实例Q?

struct ObjectA {
   // objectA 的数?nbsp;
}

struct ObjectB {
   // objectB 的数?nbsp;
}

// 同时使用 objectA ?nbsp;objectB

//
// 使用指针 
//
struct ObjectB {
   struct ObjectA * pObjA;
   // objectB 的数?nbsp;
}

//
// 使用嵌入
作者:121.30.67.*
2006-11-26 23:15 回复此发a 

8 堆和栈的区别 (转脓)
//
struct ObjectB {
   struct ObjectA pObjA;
   // objectB 的数?nbsp;
}

//
// 集合 – 在另一对象内?nbsp;objectA ?nbsp;objectB
//

struct ObjectX {
   struct ObjectA  objA;
   struct ObjectB  objB;
}

避免使用指针兌两个数据l构。如果用指针关联两个数据结构,前面实例中的对象 A ?nbsp;B 被分别分配和释放。这会增加额外开销—我们要避免q种做法?


把带指针的子对象嵌入父对象。当对象中有指针Ӟ则意味着对象中有动态元素(癑ֈ之八十)和没有引用的C|。嵌入增加了位置从而减了q一步分?释放的需求。这提高应用程序的性能?


合ƈ对象Ş成大对象Q聚合)。聚合减分配和释放的块的数量。如果有几个开发者,各自开发设计的不同部分Q则最l会有许多小对象需要合q。集成的挑战是要找到正的聚合边界?


内联~冲够满百分之八十的需要(aka 80-20 规则Q。个别情况下Q需要内存缓冲区来保存字W串/二进制数据,但事先不知道d节数。估计ƈ内联一个大能满癑ֈ之八十需要的~冲区。对剩余的百分之二十Q可以分配一个新的缓冲区和指向这个缓冲区的指针。这P减分配和释放调用q增加数据的位置I间Q从Ҏ上提高代码的性能?


在块中分配对象(块化Q。块化是以组的方式一ơ分配多个对象的Ҏ。如果对列表的项q箋跟踪Q例如对一?nbsp;{名称Q值} 对的列表Q有两种选择Q选择一是ؓ每一?#8220;名称-?#8221;对分配一个节点;选择二是分配一个能容纳Q如五个Q?#8220;名称-?#8221;对的l构。例如,一般情况下Q如果存储四对,可减少节点的数量,如果需要额外的I间数量Q则使用附加的链表指针?nbsp;
块化是友好的处理器高速缓存,特别是对?nbsp;L1-高速缓存,因ؓ它提供了增加的位|?nbsp;—不用说对于块分配,很多数据块会在同一个虚拟页中?

正确使用 _amblksiz。C q行?nbsp;(CRT) 有它的自定义前端分配E序Q该分配E序从后端(Win32 堆)分配大小?nbsp;_amblksiz 的块。将 _amblksiz 讄高的D潜在地减对后端的调用次数。这只对q泛使用 CRT 的程序适用?
使用上述技术将获得的好处会因对象类型、大及工作量而有所不同。但总能在性能和可升羃性方面有所收获。另一斚wQ代码会有点ҎQ但如果l过深思熟虑,代码q是很容易管理的?

其他提高性能的技?
下面是一些提高速度的技术: 

使用 Windows NT5 ?nbsp;
׃几个同事的努力和辛勤工作Q?998 q初 Microsoft Windows(R) 2000 中有了几个重大改q:

改进了堆代码内的锁定。堆代码Ҏ堆一个锁。全局锁保护堆数据l构Q防止多U程式的使用。但不幸的是Q在高通信量的情况下,堆仍受困于全局锁,D高竞争和低性能。Windows 2000 中,锁内代码的界区竞争的可能性减到最?从而提高了可׾~性?


使用 “Lookaside”列表。堆数据l构对块的所有空闲项使用了大在 8 ?nbsp;1,024 字节Q以 8-字节递增Q的快速高速缓存。快速高速缓存最初保护在全局锁内。现在,使用 lookaside 列表来访问这些快速高速缓存空闲列表。这些列表不要求锁定Q而是使用 64 位的互锁操作Q因此提高了性能?


内部数据l构法也得到改q?
q些改进避免了对分配高速缓存的需求,但不排除其他的优化。?nbsp;Windows NT5 堆评估您的代码;它对于 1,024 字节 (1 KB) 的块Q来自前端分配程序的块)是最佳的。GlobalAlloc() ?nbsp;LocalAlloc() 建立在同一堆上Q是存取每个q程堆的通用机制。如果希望获得高的局部性能Q则使用 Heap(R) API 来存取每个进E堆Q或为分配操作创q堆。如果需要对大块操作Q也可以直接使用 VirtualAlloc() / VirtualFree() 操作?

上述改进已在 Windows 2000 beta 2 ?nbsp;Windows NT 4.0 SP4 中用。改q后Q堆锁的竞争率显著降低。这使所?nbsp;Win32 堆的直接用户受益。CRT 堆徏立于 Win32 堆的剙Q但它用自q块堆,因而不能从 Windows NT 改进中受益。(Visual C++ 版本 6.0 也有改进的堆分配E序。)
作者:121.30.67.*
2006-11-26 23:15 回复此发a 

9 堆和栈的区别 (转脓)

使用分配高速缓?nbsp;
分配高速缓存允讔R速缓存分配的块,以便来重用。这能够减少对进E堆Q或全局堆)的分?释放调用的次敎ͼ也允许最大限度的重用曄分配的块。另外,分配高速缓存允许收集统计信?以便较好地理解对象在较高层次上的使用?

典型圎ͼ自定义堆分配E序在进E堆的顶部实现。自定义堆分配程序与pȝ堆的行ؓ很相伹{主要的差别是它在进E堆的顶部ؓ分配的对象提供高速缓存。高速缓存设计成一套固定大(?nbsp;32 字节?4 字节?28 字节{)。这一个很好的{略Q但q种自定义堆分配E序丢失与分配和释放的对象相关的“语义信息”?nbsp;

与自定义堆分配程序相反,“分配高速缓?#8221;作ؓ每类分配高速缓存来实现。除能够提供自定义堆分配E序的所有好处之外,它们q能够保留大量语义信息。每个分配高速缓存处理程序与一个目标二q制对象兌。它能够使用一套参数进行初始化Q这些参数表Cƈ发别、对象大和保持在空闲列表中的元素的数量{。分配高速缓存处理程序对象维持自qU有I闲实体池(不超q指定的阀|q用私有保护锁。合在一P分配高速缓存和U有锁减了与主pȝ堆的通信量,因而提供了增加的ƈ发、最大限度的重用和较高的可׾~性?

需要用清理程序来定期查所有分配高速缓存处理程序的zd情况q回收未用的资源。如果发现没有活动,释攑ֈ配对象的池,从而提高性能?

可以审核每个分配/释放zd。第一U信息包括对象、分配和释放调用的L。通过查看它们的统计信息可以得出各个对象之间的语义关系。利用以上介l的许多技术之一Q这U关pd以用来减内存分配?

分配高速缓存也起到了调试助手的作用Q帮助您跟踪没有完全清除的对象数量。通过查看动态堆栈返回踪q和除没有清除的对象之外的签名,甚至能够扑ֈ切的失败的调用者?

MP ?nbsp;
MP 堆是对多处理器友好的分布式分配的E序包,?nbsp;Win32 SDKQWindows NT 4.0 和更新版本)中可以得到。最初由 JVert 实现Q此处堆抽象建立?nbsp;Win32 堆程序包的顶部。MP 堆创建多?nbsp;Win32 堆,q试囑ְ分配调用分布C同堆Q以减少在所有单一锁上的竞争?

本程序包是好的步?nbsp;—一U改q的 MP-友好的自定义堆分配程序。但是,它不提供语义信息和缺乏统计功能。通常?nbsp;MP 堆作?nbsp;SDK 库来使用。如果用这?nbsp;SDK 创徏可重用组Ӟ您将大大受益。但是,如果在每?nbsp;DLL 中徏立这?nbsp;SDK 库,增加工作设|?

重新思考算法和数据l构 
要在多处理器机器上׾~,则算法、实现、数据结构和g必须动态׾~。请看最l常分配和释攄数据l构。试问,“我能用不同的数据l构完成此工作吗Q?#8221;例如Q如果在应用E序初始化时加蝲了只读项的列表,q个列表不必是线性链接的列表。如果是动态分配的数组非常好。动态分配的数组减内存中的堆块和片Q从而增强性能?

减少需要的对象的数量减少堆分配程序的负蝲。例如,我们在服务器的关键处理\径上使用五个不同的对象,每个对象单独分配和释放。一起高速缓存这些对象,把堆调用从五个减到一个,显著减少了堆的负载,特别当每U钟处理 1,000 个以上的h时?

如果大量使用“Automation”l构Q请考虑从主U代码中删除“Automation BSTR”Q或臛_避免重复?nbsp;BSTR 操作。(BSTR q接Dq多的重分配和分?释放操作。)

摘要
Ҏ有^台往往都存在堆实现Q因此有巨大的开销。每个单独代码都有特定的要求Q但设计能采用本文讨论的基本理论来减堆之间的相互作用?nbsp;

评h您的代码中堆的用?


改进您的代码Q以使用较少的堆调用Q分析关键\径和固定数据l构?


在实现自定义的包装程序之前用量化堆调用成本的方法?


如果Ҏ能不满意,误?nbsp;OS l改q堆。更多这c请求意味着Ҏq堆的更多关注?


要求 C q行时组针对 OS 所提供的堆制作y的分配包装程序。随着 OS 堆的改进QC q行时堆调用的成本将减小?


操作pȝQWindows NT 家族Q正在不断改q堆。请随时x和利用这些改q?
Murali Krishnan ?nbsp;Internet Information Server (IIS) l的首席软g设计工程师。从 1.0 版本开始他p?nbsp;IISQƈ成功发行?nbsp;1.0 版本?nbsp;4.0 版本。Murali l织q?nbsp;IIS 性能l三q?nbsp;(1995-1998), 从一开始就影响 IIS 性能。他拥有威斯h?nbsp;Madison 大学?nbsp;M.S.和印?nbsp;Anna 大学?nbsp;B.S.。工作之外,他喜Ƣ阅诅R打排球和家庭烹饪?
原帖来自于:http://tieba.baidu.com/f?kz=150791801

]]>
I/O 同步Q异步,dQ非d问题http://www.shnenglu.com/jianlinzhang/archive/2009/07/10/89739.html张徏?/dc:creator>张徏?/author>Fri, 10 Jul 2009 09:30:00 GMThttp://www.shnenglu.com/jianlinzhang/archive/2009/07/10/89739.htmlhttp://www.shnenglu.com/jianlinzhang/comments/89739.htmlhttp://www.shnenglu.com/jianlinzhang/archive/2009/07/10/89739.html#Feedback0http://www.shnenglu.com/jianlinzhang/comments/commentRss/89739.htmlhttp://www.shnenglu.com/jianlinzhang/services/trackbacks/89739.html IO - 同步Q异步,dQ非d
同步QsynchronousQ?IO和异步(asynchronousQ?IOQ阻塞(blockingQ?IO和非dQnon-blockingQIO Q我怿q几个词困扰q很多hQ更痛苦的是Q如果你查阅q文献资料,你会发现不同的资料中的解释是不一LQ例如在wiki中,异步和非d被当成了一个概??br>出现q种情况的原因,我认为很大程度上是因为IOq个概念本n很宽泛Q它其实包含了好几个层面。比如说Q你可以把它看做是一个物理上的设备,也可以看做是 OS抽象出来的一个YӞq可以看做是qx写程序用的read(),write()函数Q不同的层面对于q几个词的理解也是不一L?/p>

先看一个较低的层次。如果从CPU的角度看Q其实大部分的IO都是异步的:因ؓCPU启动q个IO操作后,去q其它的事情了,一直到产生一个中断,告诉它IO完成了?br>“Most physical I/O is asynchronous—the CPU starts the transfer and goes off to do something else until the interrupt arrives. User programs are much easier to write if the I/O operations are blocking—after a read system call the program is automatically suspended until the data are available in the buffer. It is up to the operating system to make operations that are actually interrupt-driven look blocking to the user programs.” Q引?Modern Operating Systems, 2edQ?/p>

不过Q本文ƈ不想探究那么底层的东东。作为程序员Q更多的q是从应用层面来考虑。所以,以下重点介绍的是应用E序中能够采用的四种IO机制?br>Q说明,下文中图片引用自 http://www.ibm.com/developerworks/cn/linux/l-async/ Q?/p>

首先Q从最常用到的Q也是最Ҏ理解的同步阻塞IO 说v?/p>

在这个模型中Q应用程序(applicationQؓ了执行这个read操作Q会调用相应的一个system callQ将pȝ控制权交lkernelQ然后就q行{待Q这其实是被阻塞了Q。kernel开始执行这个system callQ执行完毕后会向应用E序q回响应Q应用程序得到响应后Q就不再dQƈq行后面的工作?br> 

 
例如Q?#8220;在调?read pȝ调用Ӟ应用E序会阻塞ƈ对内核进行上下文切换。然后会触发L作,当响应返回时Q从我们正在从中d的设备中q回Q,数据pUd到用L间的~冲Z。然后应用程序就会解除阻塞(read 调用q回Q?#8221;


 举一个浅昄例子Q就好比你去一个银行柜台存钱。首先,你会存q单子填好Q然后交l柜员。这里,你就好比是applicationQ单子就是调用的 system callQ柜员就是kernel。提交好单子后,你就坐在柜台前等Q相当于开始进行等待。柜员办好以后会l你一个回执,表示办好了,q就?response。然后你可以拿着回执q其它的事了。注意,q个时候,如果你办完之后马上去查̎Q存的钱已经打到你的账户上了。后面你会发玎ͼq点很重要?/p>

接下来谈同步非阻塞IO ?br>先看q个图,

 

在linux下,应用E序可以通过讄文g描述W的属性O_NONBLOCKQI/O操作可以立即q回Q但是ƈ不保证I/O操作成功?br>也就是说Q当应用E序讄了O_NONBLOCK之后Q执行write操作Q调用相应的system callQ这个system call会从内核中立卌回。但是在q个q回的时间点Q数据可能还没有被真正的写入到指定的地方。也是_kernel只是很快的返回了q个 system callQ这P应用E序不会被这个IO操作blockingQ,但是q个system call具体要执行的事情Q写数据Q可能ƈ没有完成。而对于应用程序,虽然q个IO操作很快p回了Q但是它q不知道q个IO操作是否真的成功了,如果想知道,需要应用程序主动地去问kernel?/p>

q次不是去银行存钱,而是去银行汇ƾ。同LQ你也需要填写汇Ƒ֍然后交给柜员Q柜员进行一些简单的手箋处理p够给你回执。但是,你拿到回执ƈ不意味着钱已l打CҎ的̎上。事实上Q一般汇Ƅ周期大概?4个小Ӟ如果你要以存q模式来汇Ƅ话,意味着你需要在银行{?4个小Ӟq显然是不现实的。所以,同步非阻塞IO在实际生zM也是有它的意义的?/p>

再来谈谈异步dIO ?br>在linux中,常常通过select/poll来实现这U机制?/p>

 
以图ZQ?br>和之前一P应用E序要执行read操作Q因此调用一个system callQ这个system call被传递给了kernel。但在应用程序这边,它调用system call之后Qƈ不等待kernelq回responseQ这一Ҏ和前面两U机制不一L地方。这也是Z么它被称为异步的原因。但是ؓ什么称其ؓd呢?q是因ؓ虽然应用E序是一个异步的方式Q但是select()函数会将应用E序d住,一直等到这个system call有结果返回了Q再通知应用E序。也是_“在这U模型中Q配|的是非d I/OQ然后用阻?select pȝ调用来确定一?I/O 描述W何时有操作?#8221;
所以,从IO操作的实际效果来看,异步dIO和第一U同步阻塞IO是一LQ应用程序都是一直等到IO操作成功之后Q数据已l被写入或者读取)Q才开始进行下面的工作。异步阻塞IO的好处在于一个select函数可以为多个描q符提供通知Q提高了q发性?/p>


关于提高q发性这点,我们q以银行Z说明。比如说一个银行柜収ͼ现在?0个h惛_钱。按照现在银行的做法Q一个个排队。第一个h先填存款单,然后提交Q然后柜员处理,然后l回执,成功后再轮到下一个h。大家应该都在银行排q对Q这L程是很痛苦的。如果按照异步阻塞的机制Q?0个h都填好存Ƒ֍Q然后都提交l柜収ͼ提交完之后所有的10个h在银行大厅{待。这时候会专门有个人,他会了解存款单处理的情况Q一旦有存款单处理完毕,他会回执交l相应的正在大厅{待的hQ这个拿到回执的人就可以d其他的事情了。而前面提到的q个专hQ就对应于select函数?/p>

最后,谈谈异步非阻塞IO ?br>q个概念相对前面两个反而更Ҏ理解一些?/p>

 
如图所C,应用E序提交readh的system callQ然后,kernel开始处理相应的IO操作Q而同Ӟ应用E序q不{kernelq回响应Q就会开始执行其他的处理操作Q应用程序没有被IO操作所dQ。当kernel执行完毕Q返回read的响应,׃产生一个信h执行一个基于线E的回调函数来完成这?I/O 处理q程?/p>


比如银行存钱。现在某银行新开通了一存׃务。用户之需要将存款单交l柜収ͼ然后无需{待可以离开了。柜台办好以后会l用户发送一条短信,告知交易成功。这L户不需要在柜台前进行长旉的等待,同时Q也能够得到切的消息知道交易完成?/p>


从前面的介绍中可以看出,所谓的同步和异步,在这里指的是application和kernel之间的交互方式。如果application不需要等?kernel的回应,那么它就是异步的。如果application提交完IOh后,需要等?#8220;回执”Q那么它是同步的?br>而阻塞和非阻塞,指的是application是否{待IO操作的完成。如果application必须{到IO操作实际完成以后再执行下面的操作Q那么它是阻塞的。反之,如果不等待IO操作的完成就开始执行其它操作,那么它是非阻塞的?/p>

 

本文来自CSDN博客Q{载请标明出处Q?a >http://blog.csdn.net/historyasamirror/archive/2009/06/15/4270633.aspx



]]>
使用CString的方?/title><link>http://www.shnenglu.com/jianlinzhang/archive/2009/07/02/89047.html</link><dc:creator>张徏?/dc:creator><author>张徏?/author><pubDate>Thu, 02 Jul 2009 02:58:00 GMT</pubDate><guid>http://www.shnenglu.com/jianlinzhang/archive/2009/07/02/89047.html</guid><wfw:comment>http://www.shnenglu.com/jianlinzhang/comments/89047.html</wfw:comment><comments>http://www.shnenglu.com/jianlinzhang/archive/2009/07/02/89047.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/jianlinzhang/comments/commentRss/89047.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jianlinzhang/services/trackbacks/89047.html</trackback:ping><description><![CDATA[可以使用 STL的string?nbsp;  <br>#include   <string>   <br>using   namespace   std;<br><br>但肯定不如CString功能强大Q其实在非MFCE序中用CStringQ也是可以的Q具体方法如下:<br><br>  Z使用CStringc,首先源文件必L以cppl尾的,q是因ؓvc默认对不同的扩展名采用不同的~译Ҏ和错误检查,mfc的支持文件Afx.h只有由cpp为扩展名的文件包含才能够正常~译。对于exe和库要采用不同的方式。下面分别讨论:<br><br>  一、在非dll或者lib的工E里Q用CString非常ҎQ只要两步:<br><br>  1、对于没有包?lt;Windows.h>的stdafx.h中,只要包含了afx.h卛_Q而对于已l包含了<windows.h>的stdafx.h, 一定需要保证afx.h在windows.h之前被包含。另外由于默认的控制台程序采用的单线E运行库Q我们要把它Ҏ多线E库Q这些工作只要在stdafx.h中进行修改就可以了(详细信息可以参考候捷?lt;<mfc 深入出>>Q,我用的一个stdafx.h的例子如下(q是一个从向导生成的win32位GUI的程序的stdafx.h修改的)Q?br><br>// stdafx。h<br>#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)<br>#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_<br><br>#if _MSC_VER > 1000<br>#pragma once<br>#endif // _MSC_VER > 1000<br><br>#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers<br><br>#include <afx.h> // 加在q里<br><br>// Windows Header Files:<br>#include <windows.h><br><br>// C RunTime Header Files<br>#include <stdlib.h><br>#include <malloc.h><br>#include <memory.h><br>#include <tchar.h><br>#ifdef _DEBUG<br>  #pragma comment(lib, "libcmtd.lib")<br>#else<br>  #pragma comment(lib, "libcmt.lib")<br>#endif<br>// Local Header Files<br><br>#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_)<br>q样可以在E序中正怋用CStringcM?br><br>  二、在dll或者lib的工E中Q由于afx.h默认带了一个DllMainQ致使要使用CStringc需要几个步骤?br><br>  1、首先和控制台程序一P如果~译环境讄了采用单U程? 要改成多U程库,q个可以从工E属性里q行修改Q详l信息可以参考候捷?lt;<mfc 深入出>>. 下面l出的是我常用的方式Q可以直接把它复制到工程里用:<br><br>  #ifdef _DEBUG<br>  #pragma comment(lib, "libcmtd.lib")<br>  #else<br>  #pragma comment(lib, "libcmt.lib")<br>  #endif   <br>2、工E目录下创徏一个DLLMODUL.CPP文gQƈ且把它加入到当前工程中?br><br>  3、打开DLLMODUL.CPP文gQ编辑这个文件ؓq样Q?br>  #include "stdafx.h"<br>  #ifdef _DEBUG<br>  #undef THIS_FILE<br>  static char THIS_FILE[] = __FILE__;<br>  #endif<br><br>  #define new DEBUG_NEW<br><br>  /////////////////////////////////////////////////////////////////////////////<br>  // global data<br><br>  // The following symbol used to force inclusion of this module for _USRDLL<br>  #ifdef _X86_<br>  extern "C" { int _afxForceUSRDLL; }<br>  #else<br>  extern "C" { int __afxForceUSRDLL; }<br>  #endif <br>4、打开stdafx.hQ把afx.h包含在windows.h前面。现在可以正常的使用CString了? <img src ="http://www.shnenglu.com/jianlinzhang/aggbug/89047.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jianlinzhang/" target="_blank">张徏?/a> 2009-07-02 10:58 <a href="http://www.shnenglu.com/jianlinzhang/archive/2009/07/02/89047.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于 vs2005 dcL者变?出错问题的解x?/title><link>http://www.shnenglu.com/jianlinzhang/archive/2009/05/26/85768.html</link><dc:creator>张徏?/dc:creator><author>张徏?/author><pubDate>Tue, 26 May 2009 02:11:00 GMT</pubDate><guid>http://www.shnenglu.com/jianlinzhang/archive/2009/05/26/85768.html</guid><wfw:comment>http://www.shnenglu.com/jianlinzhang/comments/85768.html</wfw:comment><comments>http://www.shnenglu.com/jianlinzhang/archive/2009/05/26/85768.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.shnenglu.com/jianlinzhang/comments/commentRss/85768.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jianlinzhang/services/trackbacks/85768.html</trackback:ping><description><![CDATA[当在vs2005中添加类或者变量是会出?“当前面脚本发生错误”的提C,如下图所C:<img border=0 alt="" src="http://www.shnenglu.com/images/cppblog_com/jianlinzhang/1.jpg" width=625 height=533><br><br>该解x案如下:<br>Q?Q下载vs2005 补丁,下蝲链接为:<a target=_blank><u><font color=#810081>Microsoft Visual C++ 2005 SP1 Redistributable Package (x86)</font></u></a> Q安装之。。?br>Q?Q下载需要修Ҏ册表的一个工E?下蝲地址为:<a >http://download.csdn.net/source/1145363</a>Q运行之。。?br>xQ问题就已解冻I<br><br>当然引v该问题的主要原因是由于IE8的用,如果你觉得以上方法比较复杂,可直接卸载掉IE8.。。?br><br>在此Q我要感?a >http://jiangsheng.spaces.live.com/blog/cns!1BE894DEAF296E0A!878.entry</a> 文章的博丅R。。? <img src ="http://www.shnenglu.com/jianlinzhang/aggbug/85768.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jianlinzhang/" target="_blank">张徏?/a> 2009-05-26 10:11 <a href="http://www.shnenglu.com/jianlinzhang/archive/2009/05/26/85768.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>socket 同步 异步 d 非阻?/title><link>http://www.shnenglu.com/jianlinzhang/archive/2009/05/18/83297.html</link><dc:creator>张徏?/dc:creator><author>张徏?/author><pubDate>Mon, 18 May 2009 09:36:00 GMT</pubDate><guid>http://www.shnenglu.com/jianlinzhang/archive/2009/05/18/83297.html</guid><wfw:comment>http://www.shnenglu.com/jianlinzhang/comments/83297.html</wfw:comment><comments>http://www.shnenglu.com/jianlinzhang/archive/2009/05/18/83297.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/jianlinzhang/comments/commentRss/83297.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/jianlinzhang/services/trackbacks/83297.html</trackback:ping><description><![CDATA[<p>同步Q函数没有执行完不返回,U程被挂?</p> <p>dQ没有收完数据函Cq回Q线E也被挂?/p> <p>异步Q函数立卌回,通过事g或是信号通知调用?/p> <p>非阻塞:函数立即q回Q通过select通知调用?/p> <p>q样看来异步和非d有什么区别呢Q?/p> <p>异步=非阻塞?</p> <p>同步是在操作pȝ层面上,d是在套接字上Q?/p> <p>Reactor是同?Proactor是异步?</p> <p><strong>回答Q?/strong></p> <p>同步、异步、阻塞和非阻塞的概念</p> <p>  在进行网l编E时Q我们常常见到同步、异步、阻塞和非阻塞四U调用方式。这些方式彼此概念ƈ不好理解。下面是我对q些术语的理解?/p> <p><strong>同步</strong><br>  所谓同步,是在发Z个功能调用时Q在没有得到l果之前Q该调用׃q回。按照这个定义,其实l大多数函数都是同步调用Q例如sin, isdigit{)。但是一般而言Q我们在说同步、异步的时候,Ҏ那些需要其他部件协作或者需要一定时间完成的d。最常见的例子就?SendMessage。该函数发送一个消息给某个H口Q在Ҏ处理完消息之前,q个函数不返回。当Ҏ处理完毕以后Q该函数才把消息处理函数所q回?LRESULTD回给调用者?/p> <p><strong>异步</strong><br>  异步的概念和同步相对。当一个异步过E调用发出后Q调用者不能立d到结果。实际处理这个调用的部g在完成后Q通过状态、通知和回调来通知调用者。以 CAsycSocketcMؓ例(注意QCSocket从CAsyncSocketzQ但是v功能已经由异步{化ؓ同步Q,当一个客L通过调用 Connect函数发出一个连接请求后Q调用者线E立d以朝下运行。当q接真正建立h以后Qsocket底层会发送一个消息通知该对象。这里提到执?部g和调用者通过三种途径q回l果Q状态、通知和回调。可以用哪一U依赖于执行部g的实玎ͼ除非执行部g提供多种选择Q否则不受调用者控制。如果执行部 件用状态来通知Q那么调用者就需要每隔一定时间检查一ơ,效率很低(有些初学多线E编E的人,dƢ用一个@环去查某个变量的|q其实是一U很严重 的错误)。如果是使用通知的方式,效率则很高,因ؓ执行部g几乎不需要做额外的操作。至于回调函敎ͼ其实和通知没太多区别?/p> <p><strong>d</strong><br>  d调用是指调用l果q回之前Q当前线E会被挂赗函数只有在得到l果之后才会q回。有Z怼把阻塞调用和同步调用{同hQ实际上他是不同的。对于同 步调用来_很多时候当前线E还是激zȝQ只是从逻辑上当前函数没有返回而已。例如,我们在CSocket中调用Receive函数Q如果缓冲区中没有数 据,q个函数׃一直等待,直到有数据才q回。而此Ӟ当前U程q会l箋处理各种各样的消息。如果主H口和调用函数在同一个线E中Q除非你在特D的界面?作函C调用Q其实主界面q是应该可以h。socket接收数据的另外一个函数recv则是一个阻塞调用的例子。当socket工作在阻塞模式的时候, 如果没有数据的情况下调用该函敎ͼ则当前线E就会被挂vQ直到有数据为止?/p> <p><strong>非阻?/strong><br>  非阻塞和d的概늛对应Q指在不能立d到结果之前,该函C会阻塞当前线E,而会立刻q回?/p> <p>  对象的阻塞模式和d函数调用<br>  对象是否处于d模式和函数是不是d调用有很强的相关性,但是q不是一一对应的。阻塞对象上可以有非d的调用方式,我们可以通过一定的API去轮询状 态,在适当的时候调用阻塞函敎ͼ可以避免阻塞。而对于非d对象Q调用特D的函数也可以进入阻塞调用。函数select是q样的一个例子?/p> <p><strong>d通信 </strong></p> <p>--------------------------------------------------------------------------------</p> <p>  通过重叠通信和计在许多pȝ能提高性能。由一个智能通信控制器自动地执行通信的系l是真实的。轻Q重U烦是取得这U重叠的一U机制。导致好性能?一个可选的机制是用非d通信。一个阻塞发送开始调用初始化q个发送操作,但不完成它。在q个消息被从q个发送缓存拷Z前,q个发送开始调用将q回?需要一个独立的“发送完?#8221;调用完成q个通信Q例如,验从发送缓存拷出的数据。用适当的硬Ӟ在发送被初始化后和它完成以前Q来自发送者存储的数据转换 可以和在发送者完成的计算同时q行。类似地Q一个非d“接收开始调?#8221;初始化这个接收操? 但不完成它。在一个消息被存入q个接收~存以前Q这个调用将q回。须要一个独立的“接收完成”调用完成q个接收操作Qƈ验被接收到这个接收缓存的数据?用适当的硬Ӟ在接收操作初始化后和它完成以前,到接收者存储的数据转换可以和计同时进行。非d接收的用虽着信息较早地在接收~存位置被提供,也可 以避免系l缓存和存储器到存储器拷贝?/p> <p>  非阻塞发送开始调用能使用与阻塞发送一L四种模式: 标准, ~存, 同步和准备好模式。这些具有同L意义。无Z个匹配接收是否已dQ能开始除“准备?#8221;以外的所有模式的发送;只要一个匹配接收已dQ就能开始一个非 d“准备?#8221;发送。在所有情况下Q发送开始调用是局部的Q无论其它进E的状态如何,它立刻返回。如果这个调用得一些系l资源用完,那么它将p|q返?一个错误代码。高质量的MPI实现应保证这U情况只?#8220;病?#8221;时发生。即Q一个MPI实现能支持大数量挂起非d操作。  </p> <p>  当数据已被从发送缓存拷出时Q这个发送完成调用返回。它可以带有附加的意义,q取决于发送模式。 </p> <p>  如果发送模式是“同步?#8221;Q那么只有一个匹配接收已开始这个发送才能完成。即Q一个接收已被登入,q已和这个发送匹配。这Ӟq个发送完成调用是?局部的。注意,在接收完成调用发生以前,如果一个同步、非d发送和一个非d接收匚w, 它可以完成?发送者一“知道”转换结束,它就能完成,但在接收?#8220;知道”转换结束以?。  </p> <p>  如果发送模式是“~存”Qƈ没有挂v接收Q那么消息必被~存。这Ӟ发送完成调用是局部的Q而且无论一个匹配接收的状态如何,它必L功。  </p> <p>  如果发送模式是标准的,同时q个消息被缓存,那么在一个匹配接收发生以前,发送结束调用可以返回。另一斚wQ发送完成直C个匹配接收发生才可以完成Qƈ且这个消息已被拷到接收缓存。  </p> <p>  非阻塞发送能被用d接收匚wQ反q来也可以?/p> <p>  l用L. 一个发送操作的完成, 对于标准模式可以被gq? 对于同部模式必须延迟, 直到一个匹配接收登入。这两种情况下非d发送的使用允许发送者提前于接收者进行,以便在两q程的速度斚wQ计更容忍波动。  </p> <p>  ~存和准备好模式中的非阻塞发送有一个更有限的媄响。一可能一个非d发送将q回Q而一个阻塞发送将在数据被从发送者存储拷出后q回。只要在数据拯能和计算同时的情况下Q非d发送的使用有优炏V?/p> <p>  消息发送模式隐含着由发送者初始化通信。当发送者初始化通信(数据被直接移到接收缓? q不要求排队一个挂起发送请? Ӟ如果一个接收已dQ这个通信一般将有较低的额外负担。但是,只在匚w发送已发生后,一个接收操作能完成。当非阻塞接收等待发送时Q没有阻塞接Ӟ?的用允许得到较低的通信额外负担。(l用Ll束Q?/p> <br><br>原文出处Q?a >http://www.kuqin.com/networkprog/20090221/35947.html</a> <img src ="http://www.shnenglu.com/jianlinzhang/aggbug/83297.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/jianlinzhang/" target="_blank">张徏?/a> 2009-05-18 17:36 <a href="http://www.shnenglu.com/jianlinzhang/archive/2009/05/18/83297.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OpenMPq行E序设计http://www.shnenglu.com/jianlinzhang/archive/2009/05/14/82906.html张徏?/dc:creator>张徏?/author>Thu, 14 May 2009 01:11:00 GMThttp://www.shnenglu.com/jianlinzhang/archive/2009/05/14/82906.htmlhttp://www.shnenglu.com/jianlinzhang/comments/82906.htmlhttp://www.shnenglu.com/jianlinzhang/archive/2009/05/14/82906.html#Feedback0http://www.shnenglu.com/jianlinzhang/comments/commentRss/82906.htmlhttp://www.shnenglu.com/jianlinzhang/services/trackbacks/82906.html
OpenMP的指令有以下一些:
       parallelQ用在一个代码段之前Q表CD代码将被多个线Eƈ行执?/div>
       forQ用于for循环之前Q将循环分配到多个线E中q行执行Q必M证每ơ@环之间无相关性?/div>
       parallel forQ?parallel ?for语句的结合,也是用在一个for循环之前Q表Cfor循环的代码将被多个线Eƈ行执行?/div>
       sectionsQ用在可能会被ƈ行执行的代码D之?/div>
       parallel sectionsQparallel和sections两个语句的结?/div>
       criticalQ用在一D代码界区之前
       singleQ用在一D只被单个线E执行的代码D之前,表示后面的代码段被单线E执行?/div>
       flushQ?/div>
barrierQ用于ƈ行区内代码的U程同步Q所有线E执行到barrier时要停止Q直到所有线E都执行到barrier时才l箋往下执行?/div>
atomicQ用于指定一块内存区域被制动更新
masterQ用于指定一D代码块׃U程执行
orderedQ?用于指定q行区域的@环按序执行
threadprivate, 用于指定一个变量是U程U有的?/div>
OpenMP除上q指令外Q还有一些库函数Q下面列出几个常用的库函敎ͼ
       omp_get_num_procs, q回q行本线E的多处理机的处理器个数?/div>
       omp_get_num_threads, q回当前q行区域中的zdU程个数?/div>
       omp_get_thread_num, q回U程?/div>
       omp_set_num_threads, 讄q行执行代码时的U程个数
omp_init_lock, 初始化一个简单锁
omp_set_lockQ?上锁操作
omp_unset_lockQ?解锁操作Q要和omp_set_lock函数配对使用?/div>
omp_destroy_lockQ?omp_init_lock函数的配Ҏ作函敎ͼ关闭一个锁
 
OpenMP的子句有以下一?/div>
private, 指定每个U程都有它自q变量U有副本?/span>
firstprivateQ?/span>指定每个U程都有它自q变量U有副本Qƈ且变量要被承主U程中的初倹{?/span>
lastprivateQ?/span>主要是用来指定将U程中的U有变量的值在q行处理l束后复制回ȝE中的对应变量?/span>
reduceQ?/span>用来指定一个或多个变量是私有的Qƈ且在q行处理l束后这些变量要执行指定的运?/span>
nowaitQ?/span>忽略指定中暗含的{待
num_threadsQ?/span>指定U程的个?/span>
scheduleQ?/span>指定如何调度for循环q代
sharedQ?/span>指定一个或多个变量为多个线E间的共享变?/span>
orderedQ?/span>用来指定for循环的执行要按顺序执?/span>
copyprivateQ?/span>用于single指o中的指定变量为多个线E的׃n变量
copyinQ?/span>用来指定一?/span>threadprivate的变量的D用主U程的D行初始化?/span>
defaultQ?/span>用来指定q行处理区域内的变量的用方式,~省?/span>shared



















文章出处Q?br>http://blog.csdn.net/drzhouweiming/archive/2006/08/28/1131537.aspx
http://blog.csdn.net/drzhouweiming/archive/2006/09/04/1175848.aspx

]]>office 2007正版验证http://www.shnenglu.com/jianlinzhang/archive/2009/05/11/82532.html张徏?/dc:creator>张徏?/author>Mon, 11 May 2009 01:23:00 GMThttp://www.shnenglu.com/jianlinzhang/archive/2009/05/11/82532.htmlhttp://www.shnenglu.com/jianlinzhang/comments/82532.htmlhttp://www.shnenglu.com/jianlinzhang/archive/2009/05/11/82532.html#Feedback7http://www.shnenglu.com/jianlinzhang/comments/commentRss/82532.htmlhttp://www.shnenglu.com/jianlinzhang/services/trackbacks/82532.htmlKeygen:下蝲文g 点击下蝲此文?/font>
VBQF2-6K94C-KCT26-R4XQF-C2QQ8
GM26K-7MYV2-338DJ-4DKMG-DTJBJ
CTKXX-M97FT-89PW2-DHKD3-74MYJ(Enterprise密钥,2009-03-25 10:29:53试通过验证)

重新输入序列LҎ:HKEY_LOCAL_MACHINE\Software\Microsoft\Office\12.0\Registration\{90120000-0030-0000-0000-0000000FF1CE},删除子键DigitalProductID,ProductName及ProductID.重新打开Office׃提示输入序列?

已经安装Office2007的直接进行以下步?

2:打开微Y正版验证的网?
http://www.microsoft.com/genuine/default.aspx?displaylang=zh-cn

3:验证office2007,安装验证控g,验证昄p|!

4:用附件内OGACheckControl.dll文g:版本号ؓ:1.7.105.14,替换windows\system32\ 目录下同名文件?br>OGACheckControl.dll文g复制_脓到windows\system32\ 目录下即可替?64位系lؓsystem64\目录?
注意:OGACheckControl.dll文g的版本号与系lwindows\system32\下同名文件版本号一?br>Dll下蝲:下蝲文g 点击下蝲此文?/font>

5:再次验证office2007,通过微Y的正版验?

注意:2008q?0?0日微软更新OGACheckControl.dll文g,最新版本号?1.7.105.14,在未替换OGACheckControl.dll文g不能通过正版验证前不要打开Moffice2007lg,以免出现"星星"警告!

版本号ؓ"1.7.111.0"的OGACheckControl.dll文g:下蝲文g 点击下蝲此文?/font>

已经不幸中招?星星"警告?L附g中OGA卸蝲工具,解压后点鼠标右键中卸?直接点击不能卸蝲,卸蝲OGACheckControl.dll文g,重启计算?更换office安装序列?用附件中OGACheckControl.dll重新替换pȝwindows\system32\ 下同名文?再激zoffice2007.
星星卸蝲:下蝲文g 点击下蝲此文?/font>
或者干脆结束掉星星q替换掉星星E序.可用下面的批处理文g.
下蝲文g 点击下蝲此文?/font>

Office下蝲(推荐q雷):
企业?ftp://ribbitar.3322.org/Soft/MicrosoftOfficeEnterprise2007.iso
专业?ftp://ribbitar.3322.org/Soft/MicrosoftOfficeProfessionalPlus2007.iso




转蝲于:
http://1vr.cn/article.asp?id=411

]]>
char* String CString比较http://www.shnenglu.com/jianlinzhang/archive/2009/05/06/82015.html张徏?/dc:creator>张徏?/author>Wed, 06 May 2009 02:14:00 GMThttp://www.shnenglu.com/jianlinzhang/archive/2009/05/06/82015.htmlhttp://www.shnenglu.com/jianlinzhang/comments/82015.htmlhttp://www.shnenglu.com/jianlinzhang/archive/2009/05/06/82015.html#Feedback0http://www.shnenglu.com/jianlinzhang/comments/commentRss/82015.htmlhttp://www.shnenglu.com/jianlinzhang/services/trackbacks/82015.htmlCString/string 区别及其转化

利用MFCq行~程Ӟ我们从对话框中利用GetWindowText得到的字W串是CStringcdQCString是属于MFC的类。而一些标准C/C++库函数是不能直接对CStringcdq行操作的,所以我们经帔R到将CStringcd转化char*{等其他数据cd的情c这里ȝ备忘于此Q?/span>
首先要明,标准C中是不存在stringcd的,string是标准C++扩充字符串操作的一个类。但是我们知道标准C中有string.hq个头文Ӟq里要区分清楚,此string非彼string。string.hq个头文件中定义了一些我们经常用到的操作字符串的函数Q如Qstrcpy、strcat、strcmp{等Q但是这些函数的操作对象都是char*指向的字W串?而C++的stringcL作对象是stringcd字符Ԍ该类重装了一些运符Q添加了一些字W串操作成员函数Q得操作字W串更加方便。有的时候我们要string串和char*串配合用,所以也会涉及到q两个类型的转化问题?br>
1.CString
和string的{?/strong>
stringstr="ksarea";
CStringcstr(str.c_str());//或者CString cstr(str.data());初始化时才行
cstr=str.c_str();或?/span>cstr=str.data();
str=cstr.GetBuffer(0); //CString -> string
cstr.format("%s", str.c_str()); //string->CString
cstr.format("%s", str.data()); //string->CString
str = LPCSTR(cstr); //CString->string
/*c_str()和data()区别是:前者返回带'\0'的字W串Q后者则q回不带'\0'的字W串*/
2.CString和int的{?/span>
inti=123;
CStringstr;
str.format("%d",i);//int->CString
其他的基本类型{化类?/span>
i=atoi(str);//CString->int q有(atof,atol)
3.char*和CString的{?/span>
CStringcstr="ksarea";
char* ptemp=cstr.getbuffer(0);
char* str;
strcpy(str,ptemp);//CString->char*
cstr.releasebuffer(-1);

char*str="lovesha";
CStringcstr=str;//char*->CString string
cd不能直接赋值给CString
至于int与float、string与char*之间的{化可以用强制{化,或者标准库函数q行。对于CString与其他类型的转化Ҏ很多Q但其实都殊途同归,朝着一个方向即类型首先{化ؓchar*cdQ因为char*是不同类型之间的桥梁。得到char*cdQ{化ؓ其他cd非常容易了?/span>













主要有以下文章:
http://blog.csdn.net/bitxinhai/archive/2008/04/14/2292014.aspx
http://www.vczx.com/article/show.php?id=845

http://www.vczx.com/article/show.php?id=846



]]>破解qq的一pd问题http://www.shnenglu.com/jianlinzhang/archive/2009/05/04/81834.html张徏?/dc:creator>张徏?/author>Mon, 04 May 2009 08:15:00 GMThttp://www.shnenglu.com/jianlinzhang/archive/2009/05/04/81834.htmlhttp://www.shnenglu.com/jianlinzhang/comments/81834.htmlhttp://www.shnenglu.com/jianlinzhang/archive/2009/05/04/81834.html#Feedback0http://www.shnenglu.com/jianlinzhang/comments/commentRss/81834.htmlhttp://www.shnenglu.com/jianlinzhang/services/trackbacks/81834.html要看讉K受限的QQI间很简单啊,用手?

在地址栏里输入

http://qqxoo.com/main.html?qqid=80224567   q样可能看Ҏ的空?
http://qqshow-user.tencent.com/80224567/11/00 看MM的QQl?
http://shuqian.qq.com/80224567/  QQ        书签
http://h.qbar.qq.com/80224567 q个是看她的Q?
http://shop.paipai.com/80224567 看MM的拍?
http://wenwen.soso.com/z/ShowUser.e?sp=80224567 q个是什么呢Q问?
http://images.5d6d.net/dz61/smilies/default/mad.gif[/img]Q]http://wpa.qq.com/pa?p=1Q?4
  q个是查看好友在不在qq个?QMM是不是在U?


用手工的是很?不信p?反正也就一分钟

PS:U色部分Ҏ你想的QQ可以了
原帖来自Q?a >http://qzone.qq.com/blog/80224567-1239195902



]]>
þþƷư| ҹþƷþþþ| þAVۺϺɫ| ޹˾þһWWW| þۺۺϾþ97ɫ| ŷ޹Ʒþѿ| þþƷþ| ݺɫþۺ| ˾þˬ| 99þþþƷ| ҹƷþþþþ| þþƷ| ҹҹþ| Ʒþþþһ| ƷŮͬһþ| bƷþþþþþ| þѴƬ| ھƷۺϾþþ40p| þþƷ| Ʒþþþ㽶| պƷþþþþ| þþþùƷ۲ӰԺ | þù| ƷۺϾþ| þó鱬Ļ| Ʒ99þþþþö| þþƷƷ| ճˮþ޾Ʒtv| ˾þô߽ۺͼƬ| ƷþþþùA| 99þþƷһ| þɫۺ| Ʒ99þþþ | þùƷþþ| պŷ޹ƷĻþþ| ɫþþۺ| þùƷþþ| þþ| ŮһaëƬþw| Ըߺþþþþþþ| ɫþþþSWAGƷ|