Feeds:
Posts
Comments

A "calling convention" is the way in which a function is called. The standard __cdecl is what has been used up until now, other common ones are __stdcall, __fastcall, and __thiscall, a less common convention used when writing hacks is __declspec(naked).

__cdecl is the default calling convention on most C compilers. The properties are as follows:

  • The caller places all the parameters on the stack
  • The caller removes the parameters from the stack (often by adding the total size added to the stack pointer)

__stdcall is another common calling convention. The properties are:

  • The caller places all the parameters on the stack
  • The called function removes the parameters from the stack, often by using the return instruction with a parameter equal to the number of parameters, "ret xx"

The most useful part about __stdcall is that it tells a reverse engineer how many parameters are passed to any given function. In cases where no examples of the function being called may be found (possibly because it’s an exported DLL function), it is easier to check the return than to enumerate local variables.

__fastcall is the final common calling convention seen. All implementations of __fastcall pass parameters in registers, although Microsoft and Borland, for example, use different registers. Here are the properties of Microsoft’s __fastcall implementation:

  • First two parameters are passed in ecx and edx, respectively
  • Third parameter and on are passed on the stack, as usual
  • Functions clean up their own stack, if necessary

Recognizing a __fastcall function is easy: look for ecx and edx being used without being initialized in a function.

A __fastcall with no parameters is identical to __cdecl and __stdcall with no parameters, and a __fastcall with a single parameter looks like __thiscall.

__thiscall is very similar to __stdcall, except that a pointer to the class whose member is being called is passed in ecx.

  • ecx is assigned a pointer to the class whose member is being called
  • The parameters are placed on the stack, the same as __stdcall
  • The function cleans itself up, the same as __stdcall

__declspec(naked) is a Visual Studio-specific convention, can’t really be identified in assembly, since it’s identical to __cdecl once it reaches assembly. However, the special property of this convention is that the compiler will generate no code in a function. This allows the program, in a __asm{} block, to write everything from preserving registers to allocating local variables and returning. This is useful when patching a jump in the middle of code, since it prevents the function from changing registers without the programmer’s knowledge.

1. Storage Classes

– Storage class specifiers tell compiler the duration and visibility of the variables or objects declared, as well as, where the variables or objects should be stored.
– In C / C++ there are 4 different storage classes available: automatic, external, static and register.

Automatic Variable – auto
– Local variables are variables declared within a function or blocks (after the opening brace, { of the block). Local variables are automatic by default. This means that they come to existence when the function in which it is declared is invoked and disappears when the function ends.
– Automatic variables are declared by using the keyword auto. But since the variables declared in functions are automatic by default, this keyword may be dropped in the declaration as you found in many source codes.
– The same variable names may be declared and used in different functions, but they are only known in the functions in which they are declared. This means, there is no confusion even if the same variables names are declared and used in different functions.
– Examples if we want explicitly declare the automatic type:

auto int x, y, z = 30;
auto char firstname;

– Same as:

int x, y, z = 30;
char firstname;

External Variable – extern
– External variables are variables that are recognized globally, rather than locally. In other words, once declared, the variable can be used in any line of codes throughout the rest of the program.
– A variable defined outside a function is external. An external variable can also be declared within the function that uses it by using the keyword extern hence it can be accessed by other code in other files.
– Program segment example:

int value1;
char name;
double value2;
//three externally defined variables
main()
{
    extern int value1;
    extern char name;
    extern double value2;
    //three externally defined variables
    //can be accessed from outside of this main()
    extern value3;
    //can be accessed from outside of this main()
    …
}

– Note that the group of extern declarations may be omitted entirely if the original definition occurs in the same file and before the function that uses them.
– Therefore in the above example, the three extern declarations may be dropped. However, including the extern keyword explicitly will allow the function to use external variable even if it is defined later in a file or even in a different file provided both files will be compiled and linked together.

Static Variable – static
– In a single file program, static variables are defined within individual functions that they are local to the function in which they are defined. Static variables are local variables that retain their values throughout the lifetime of the program. In other words, their same (or the latest) values are still available when the function is re-invoked later.
– Their values can be utilized within the function in the same manner as other variables, but they cannot be accessed from outside of their defined function.
– The static has internal linkage (that is not visible from outside) except for the static members of a class that have external linkage.

Register Variable – register
– The above three classes of variables are normally stored in computer memory. Register variables however are stored in the processor registers, where they can be accessed and manipulated faster. Register variables, like automatic variables, are local to the function in which they are declared.
– Defining certain variables to be register variables does not, however, guarantee that they will actually be treated as register variables.
– Registers will be assigned to these variables by compiler so long as they are available. If a register declaration cannot be fulfilled, the variables will be treated as automatic variables. So, it is not a mandatory for the compiler to fulfill the register variables.
– Usually, only register variables are assigned the register storage class. If all things equal, a program that makes use of register variables is likely to run faster than an identical program that uses just automatic variables.

2. Constant Values – const

– In the most basic form, the const keyword specifies that a variable’s value is constant and tells the compiler to prevent the programmer from modifying it.
– Example of the pointer declaration using const is shown below:

//Pointer to constant int
int const *PtrVar;
//Pointer to constant int
int const (*PtrVar);
//Constant pointer to int
int *const PtrVar;
//Constant pointer to int
int (*const PtrVar);

– Program example:

//const variable
#include <iostream>
#include <stdlib.h>
int main()
{
    //p = 10 is a constant value, cannot be modified
    //during the program execution…
    const int p = 10;
    cout<<"q = p + 20 = "<<(p + 20)<<" where, p = 10"<<endl;
    //The following code should generate error, because
    //we try to modify the constant value…
    //uncomment, recompile notice the error…
    //p = 15;
    //–p;
    system("pause");
}

– We can use the const keyword instead of the #define preprocessor directive to define constant values.
– In C, constant values default to external linkage, so they can appear only in source files but in C++, constant values default to internal linkage, which allows them to appear in header files.
– The const also can be used in pointer declaration. A pointer to a variable declared as const can be assigned only to a pointer that is also declared as const.
– Another program segment examples:

//a const pointer to a variable…
#include <iostream>
#include <stdlib.h>
int main()
{
    //declare the pointers and let they point
    //to something…
    //non const pointer…
    char *BuffOne = NULL, *BuffTwo = NULL;
    //a constant pointer…
    //assign the BuffOne pointer to PtrOne pointer
    char *const PtrOne = BuffOne;
    //Let it point to some data…
    *PtrOne = ‘z’;
    cout<<"The value pointed by constant pointer is"<<*PtrOne<<endl;
    //The following code will generate error, because we try to assign non const pointer to const pointer…
    //PtrOne = BuffTwo;
    system("pause");
    return 0;
}

//a pointer to a const variable…
#include <iostream>
#include <stdlib.h>
int main()
{
    const char *BuffOne = "Testing";
    cout<<"The data pointed by BuffTwo is "<<BuffOne<<endl;
    //The const pointer BuffOne assigned to the
    //const pointer ThePtr is OK…
    const char *ThePtr = BuffOne;
    cout<<"The data pointed by ThePtr is "<<ThePtr<<endl;
    //The following code will generate an error
    //cannot modify the const….
    //*ThePtr = ‘z’;
    system("pause");
    return 0;
}

– The const declaration also normally used in the definition of a function’s arguments, to indicate it would not change them as shown below making the code clearer and to avoid error. int strlen(const char []);

3. Constant Member Function

– When declaring a member function with the const keyword, this specifies that it is a read only function that does not modify the object (notice the differences between variable versus object) for which it is called.
– A constant member function cannot modify any data members or call any member functions that are not constant.
– Implicitly, the const has set the ‘can’t modify’ *this pointer. This can be changed by using the mutable (preferred) or const_cast operator.
– Pointer to constant data can be used as function parameters to prevent the function from modifying a parameter passed through a pointer.
– Place the const keyword after the closing parenthesis of the argument list.
const keyword is required in both the declaration and the definition.
– Program example:

//constant member function
#include <iostream>
#include <stdlib.h>
//——–Class declaration part————
class Date
{
    int month;
public:
    //we would test the month only…
    Date (int mnt, int dy, int yr);
    //A write function, so can’t be const
    void SetMonth(int mnt);
    //A read only function declaration
    int GetMonth() const;
};

//——–Class implementation part———
Date::Date(int,int,int)
{
}
void Date::SetMonth(int mnt)
{
    //Modify the non const member variable data
    month = mnt;
}
//A read only function implementation
int Date::GetMonth() const
{
    //Does not modify anything
    return month;
}

//——-main program————
void main()
{
    Date TheDate(7,4,2004);
    //non const member function, OK
    TheDate.SetMonth(11);
    cout<<"Month of the sample date is "<<TheDate.GetMonth()<<endl;
    //another dummy const object…
    const Date BirthDate(7,4,1971);
    //Then try to modify the const object, NOT OK
    //BirthDate.SetMonth(5);
    //const member function sending message…
    BirthDate.GetMonth();
    //So, the following shouldn’t have the output data…
    cout<<"Another silly call, the month is "<<BirthDate.GetMonth()<<endl;
    system("pause");
}

– The const-ness of the function can be disabled by using the mutable keyword.

4. Keyword – volatile

– It is a type qualifier used to declare an object or variable value that can be modified by other than the statement in the source codes itself, such as interrupt service routine and memory-mapped I/O port or concurrent thread execution.
– Keep in mind that although we have to concern about these volatile variable or object, most of the compilers nowadays have their own implementation how to handle this situation mainly for Win32 applications.
– For example if you want to create multithreaded program, there are C++ compiler or project settings for multithreaded program. You have to check your compiler documentation.
– When declaring an object to be volatile, we tell the compiler not to make any assumptions concerning the value of the object while evaluating expressions in which it occurs because the value could change at any moment.
– When a name is declared as volatile, the compiler reloads the value from memory each time it is accessed by the program. Volatile codes will not be optimized by compiler to make sure that the value read at any moment is accurate.
– Without optimization, for example permitting the redundant reads, the volatile may have no effect.
– The keyword volatile is used before or after the data type declaration. They cannot appear after the first comma in a multiple variable declaration. 
– When volatile is applied to the struct or union, the entire contents of the struct or union become volatile however we can also apply the volatile to the members of struct or union individually.
– volatile also applied to classes and their member functions.

There is no binary of MySQLdb for Python 2.6 on Windows, so I have to build it from the source. We’ll need to install MySQL, MySQL Connector C and Python setuptools, and of course uncompressed MySQL-python-1.2.3.tar.gz.

Environment:

Windows 7, MySQL 5.5, MySQL Connector C 6.0.2, Python 2.6, MySQL-python-1.2.3, Microsoft VC2008(Visual Studio 9.0)

1. Edit site.cfg :

# Change the version number accordingly.
registry_key = SOFTWARE\MySQL AB\MySQL Server 5.5
# Append this line, Windows connector libs for MySQL.
connector = C:\Program Files\MySQL\MySQL Connector C 6.0.2

2. Edit setup_windows.py :

# Make the section in this file as below.
library_dirs = [ os.path.join(mysql_root, r'lib\opt') ]
library_dirs = [ os.path.join(options['connector'], r'lib\opt') ]
libraries = [ 'kernel32', 'advapi32', 'wsock32', client ]
include_dirs = [ os.path.join(mysql_root, r'include') ]
include_dirs = [ os.path.join(options['connector'], r'include') ]
extra_compile_args = [ '/Zl' ]

3. Edit C:\Python26\Lib\distutils\msvc9compiler.py :

ld_args.append(‘/MANIFESTFILE:’ + temp_manifest)
# Append this line after above line.
ld_args.append(‘/MANIFEST’)

Then go back to run setup.py build  and setup.py install.

(From: http://www.cyberciti.biz/tips/open-source-project-management-software.html)

This is an user contributed article.

Project management software is not just for managing software based project. It can be used for variety of other tasks too. The web-based software must provide tools for planning, organizing and managing resources to achieve project goals and objectives. A web-based project management software can be accessed through an intranet or WAN / LAN using a web browser. You don’t have to install any other software on the system. The software can be easy of use with access control features (multi-user). I use project management software for all of our projects (for e.g. building a new cluster farm) for issue / bug-tracking, calender, gantt charts, email notification and much more.

Obviously I’m not the only user, the following open source software is used by some of the biggest research organizations and companies world wild. For example, NASA’s Jet Propulsion Laboratory uses track software or open source project such as lighttpd / phpbb use redmine software to keep track of their projects.
You use the following top 10 software for personal or business use. Keep track of all your projects in one place and finish them successfully on time.

#1: Codendi

Codendi is an open-source collaborative development platform offered by Xerox. From only one interface, it gathers, all the needed tools for software development teams: management and versioning of code, bugs, requirements, documents, reporting, tests etc. It is mainly used for managing software project processes.

#2: Redmine

Redmine is a flexible project management web application. Written using Ruby on Rails framework, it is cross-platform and cross-database. It includes calendar and gantt charts to aid visual representation of projects and their deadlines.

#3: ProjectPier

ProjectPier is a Free, Open-Source, self-hosted PHP application for managing tasks, projects and teams through an intuitive web interface. ProjectPier will help your organization communicate, collaborate and get things done Its function is similar to commercial groupware/project management products, but allows the freedom and scalability of self-hosting.

#4: Trac

Trac is an open source, web-based project management and bug-tracking tool. Trac allows hyperlinking information between a computer bug database, revision control and wiki content. It also serves as a web interface to a version control system like Subversion, Git, Mercurial, Bazaar and Darcs.

#5: Project HQ

Project HQ is a collaborative open source project management tool, similar to Basecamp and activeCollab. Project HQ is built on open source technologies like Python, Pylons and SQLAlchemy and is fully database independent. Project HQ uses a structured workflow to assist you in managing your projects.

#6: Collabtive

Collabtive is a web-based project management software that is being published as Open Source software. The project was started in November 2007. It strives to provide an Open Source alternative to proprietary tools like Basecamp or ActiveCollab.

#7: eGroupWare

eGroupWare is a free open source groupware software intended for businesses from small to enterprises. Its primary functions allow users to manage contacts, appointments, projects and to-do lists.

It is used either via its native web-interface, making access platform-independent, or by using different supported groupware clients, such as Kontact, Novell Evolution, or Microsoft Outlook. It can also be used by mobile phone or PDA via SyncML.

#8: KForge

KForge is an open-source (GPL) system for managing software and knowledge projects. It re-uses existing best-of-breed tools such as a versioned storage (subversion), a tracker (trac), and wiki (trac or moinmoin), integrating them with the system’s own facilities (projects, users, permissions etc). KForge also provides a complete web interface for project administration as well a fully-developed plugin system so that new services and features can be easily added.

#9: OpenGoo

It is a complete online solution focused on improving productivity, collaboration, communication and management of your teams. OpenGoo main features include document management, contact management, e-mail, project management, and time management. Text documents and presentations can be created and edited online. Files can be uploaded, organized and shared, independent of file formats.

#10: ClockingIT

ClockingIT is a free Project Management solution, which helps your team stay focused and on top of things.

Ed: The following two paragraphs added by Vivek Gite:

I also use project management software to keep track of how much time I spent per client and project.

My Personal Choice

redmine is my personal choice because I like to use ruby on rails and I often work with small teams. We track networking issues, data center issues, capacity planning, trouble tickets and much more using redmine. I can track multiple projects and its flexible role-based access control make sure only authorized eyes can view the details.

Other FOSS Project Management Software Projects
  1. JotBug
  2. Bugzilla (only bug tracking)
  3. OpenProj (desktop app – replacement for MS-project)

How do you manage your IT / software and other projects? Are you using a better option? Let us know in the comments.

Nice article in highlighting code with PHP.

JetCracker

One day I needed to add some source code examples to the web-site. But there was no features for highlighting syntax. I decided to create my own tool for highlighting source code. Here I will show you how to do it using PHP with GeSHi.

View original post 98 more words

(From: http://jobsearchtech.about.com/od/gettingthejob/a/Interviewing_2.htm)

Preparing for a behavior based interview can be daunting. Here are some tips to get started:

  • Be familiar with the job for which you’re being interviewed. Read the advertisement or job description to identify which personal attributes and behaviors are likely to be key success factors for the role. For Client interviews it is advised that you research the company’s website and any external information about them from business directories etc.

    Make a note of two or three examples for each personal attribute that will best illustrate your suitability – you may want to bring these into the interview with you as prompts. Remember that different companies and industries may require different personal attributes, even for the same position. For example, ‘self-managing’ can mean very different things to different companies.

  • Be able to draw from a variety of experiences that demonstrate your skills and abilities. A good story can also combine work experience with a non-work experience (shows you can use the skill in a variety of settings). Examples may be from your work experience, your personal life or some social or other situation. Of course a unique work situation story (unless otherwise specifically requested) should take priority. Be as open, expressive and succinct as possible about each experience.
  • Let others help you out – use examples of quotes from bosses or customers, i.e., "My boss gave me a good performance review, they liked the way I stepped in to get the job done without being told to." This demonstrates your willingness to accept contribution, your flexibility and teamwork skills.
  • Think ‘STAR’ – Situation or Task, Action and Result. There are several variations of this acronym in the recruiting industry, but all of them are intended to provide structure and focus to your answers. When asked about a type of situation, the interviewer is looking at how you responded to it by via a specific example. Using the STAR model you would break your answer into the three segments of; description of the task, then the action you took, and the final measurable result.

    This makes it easier for the interviewer to visualize and record your specific behavioral responses to specific events and so gain the best impression of your potential future performance. Prepare at least one STAR response for each personal attribute you may be questioned on. Make sure you don’t use the same example for all the attributes.

  • Use recent examples. As you will be probed for detail around the situation, it is better to use events in the last 12-18 months as the detail will be clearer in your mind. Be specific as possible about your contribution and the quantitative results achieved. Specific absolute or relative (%) gains in areas such as cost or time savings will give you the interviewer a clearer picture of your abilities. If specific measurable results don’t apply to your example, you might explain how it streamlined processes, empowered others or resolved communication or productivity issues.
  • Practice telling your stories until they are vivid and concise, one to three minutes long. An interview can be likened to a marketing activity, where you are the brand. You will only get an interview because your resume and past roles suggest that you have the appropriate technical skills set (your attributes). Often what separates you from the other candidates at the interview stage is the interviewer’s belief in how you will fit into the company’s culture and specific IT team (your personal benefits).

    Remember, you are selling your technical AND personal skills. Being able to communicate your adaptability and relatedness at an interview is essential to becoming the leading candidate. This ‘story telling practice’ is an important preparation tool to assist you in creating a natural flow to your stories so that the interviewer can focus on your potential benefit to the client.

  • Ask to come back to the question. If you are stuck for an answer to a particular question, it is reasonable to ask the interviewer if you may move on to the next one and you’ll come back it.

1. 堆内存管理基础——转自《软件调试/第23章

堆是内存管理功能向应用软件提供服务的一种方式。通过堆,内存管理器将一块较大的内存空间委托给堆管理器来管理。堆管理器将大块的内存分割成不同大小的很多个小块来满足应用程序的需要。应用程序的内存需求通常是频繁而且零散的,如果把这些请求都直接传递给位于内核中的内存管理器,那么必然影响系统的性能。有了堆管理器,内存管理器就只需要处理大规模的分配请求。这样做不仅可以减轻内存管理器的负担,也可以大大缩短应用程序申请内存所需的时间,提高程序的性能。下图画出了Windows系统中实现的多级内存分配体系。

图中,我们使用不同类型的箭头来代表不同层次的内存分配方法。具体来说,用户态的代码应该调用虚拟内存分配API来从内存管理器分配内存。虚拟内存API包括VirtualAlloc、VirtualFree、VirtualLock、VirtualUnlock、VirtualProtect、VirtualQuery等。内核态的代码可以调用以上API所对应的内核函数,比如NtAllocateVirtualMemory、NtProtectVirtualMemory等。

为了满足内核空间中的驱动程序等内核态代码的内存分配需要,Windows的内核模块中实现了一系列函数来提供内存"零售"服务,为了与用户空间的堆管理器相区别,我们把这些函数统称为池管理器。池管理器公开了一组驱动程序接口(DDI)以向外提供服务,包括ExAllocatePool、ExAllocatePoolWithTag、ExFreePool等。

与内核模块中的池管理器类似,在NTDLL.DLL中实现了一个通用的堆管理器,目的为用户态的应用程序提供内存服务,通常被称为Win32堆管理器。SDK中公开了一组API来访问Win32堆管理器的功能,比如HeapAlloc、HeapFree等。

为了支持C的内存分配函数和C++的内存分配运算符,C运行库会创建一个专门的堆供这些函数使用,通常称为CRT堆。根据分配堆块的方式不同,CRT堆有三种工作模式:SBH(Small Block Heap)模式、旧SBH模式和系统模式(System Heap),当创建CRT堆时,会选择其中的一种。对于前两种模式,CRT堆会使用虚拟内存分配API从内存管理器批发大的内存块过来,然后分割成小的堆块满足应用程序的需要。对于系统模式,CRT堆只是把堆块分配请求转发给它所基于的Win32堆,因此处于系统模式的CRT堆只是对Win32堆的一种简单封装,在原来的基础上又增加了一些附加的功能。

应用程序开发商也可以实现自己的堆管理器,只要通过虚拟内存API从内存管理器"批发"内存块过来后提供给自己的客户代码使用,例如.NET里面的托管堆。

2. CRT堆的分配使用——转自《在一个模块中分配的内存在另外一个模块释放?

在Linux下,每个进程只有一个堆,在任何一个动态库模块中通过new或者malloc来分配内存的时候都是从这个唯一的堆中分配的,那么自然你在其它随便什么地方都可以释放。但是在Win下面,问题变得复杂了:
1. Windows允许一个进程中有多个堆,那么这样就需要指明一块内存要在哪个堆上分配,Win32的HeapAlloc函数就是这样设计的,给出一个堆的句柄,给出一个大小,然后返回一个指针。每个进程都至少有一个主堆,可以通过GetProcessHeap来获得,其它的堆,可以通过GetProcessHeaps取到。同样,内存释放通过HeapFree来完成,还是需要指定一个堆。
2. 这样的设计比较灵活,但是问题在于,每次分配内存的时候就必须要显式的指定一个堆,对于CRT中的new/malloc,需要特殊处理。VC的CRT创建了一个单独的堆,叫做__crtheap,它对于用户是看不见的,但是在new/malloc的实现中,都是用HeapAlloc在这个__crtheap上分配的,也就是说malloc(size)基本上可以认为等同于HeapAlloc(__crtheap, size)(当然实际上CRT内部还要维护一些内存管理的数据结构,所以并不是每次malloc都必然会触发HeapAlloc),这样new/malloc就和Windows的堆机制吻合了。
3. 如果一个进程需要动态库支持,系统在加载dll的时候,在dll的启动_DllMainCRTStartup中,会创建这个CRT堆,所以理论上有多少个dll,就有多少个CRT堆。最后主进程的mainCRTStartup 中还会创建一个为主进程服务的CRT堆。(由于顺序总是先加载dll,然后才启动main进程,所以各个dll的CRT堆地址比较小,而主进程的CRT堆地址比较大,当然排在最前面的堆是每个进程的主堆。)
4.从上面的分析中可以看出,对于CRT来说,由于每个dll都有自己的堆,所以每个dll通过new/malloc分配的内存都是在自己dll内部的那个堆上用HeapAlloc来分配的,而如果你想在其它模块中释放,那么在释放的时候HeapFree就会失败了,因为各个模块的CRT堆是不一样的。

在Windows下,一个进程存在着多个堆,除了一个主堆外,还有很多的CRT堆,用来处理通过C/C++的运行库进行的内存操作。所以使用new/malloc来分配的内存实际上都是局部的,可以在多个dll中共享,但是却必须是谁申请谁释放。当然如果在dll内部使用HeapAlloc(GetProcessHeap(), size)来分配的内存是可以在dll以外释放的,因为这时内存分配在全局的主堆上,而不是分配在dll自己的CRT堆上。

 

3. CRT堆的调试使用——转自《深入解析Win32 CRT 调试堆 () ()》

调试版本的CRT堆更关注对于堆错误的定位, 它通过以下三种手法实现以上诉求:

1. 用守护内存块包围新分配的内存, 这样就可以侦测到缓冲过载和欠载. 所谓守护内存块就是一系列被填充为0xfd的内存字节, 又被称为”无主之地”. 0xfd意为Fences(译注: 栅栏)

2. 用一个特殊的值(0xcd)初始化新申请的内存. 0xcd意为Clean Memory.

3. 同时用一个特殊的值填充(0xdd) 被释放的内存. 0xdd意为Dead Memory.

CDH(CRT Debug Heap)将大部分工作交由堆函数HeapAlloc()和HeapFree()完成, 每进程4Gb的虚地址空间的分块和管理是由Kernel32.dl中的Win32堆自己完成的.

当你调用malloc(8)分配8字节的内存时, CDH会调用HeapAlloc()申请48字节的内存, 额外的40字节被用来存放内存块的额外信息—-比如调用malloc()的源文件和行号, 以及指向上/下一个内存块的指针.在后面的列表中, 所有的CRT调试信息均被标记为红色.

HeaoAlloc()本身也需要记录簿记(bookkeeping)信息, 事实上,一个HeaoAlloc()调用会在进程地址空间里保留80字节内存, 其中8字节的簿记信息出现在真正使用的40字节之前, 剩下的32字节在真正使用的40字节之后.在下面的列表里, Win32堆簿记信息被标记为灰色.

CRT取得40字节的内存块后会填入自己的簿记信息. 头两个WORD用来存放直向”前一个”和”后一个”CRT堆内存块的指针. 这里的前后不能从字面去理解, 因为所谓指向”后一个”内存块的指针事实上指向的是时间顺序上紧邻本内存块之前分配的内存块, 相应的, 指向“前一个”的指针指向的是下一个将被分配的内存块. 之所以这样命名, 是因为内存块链表是从最后分配的内存块开始的. 同时, 为了使堆检查代码能遍历每个内存块, CDH还保存着第一块和最后一块内存的地址(_pFirstBlock和_pLastBlock).

如果调用malloc()代码所在的文件名和行号是已知的, 它们将被被保存在第三第四个字中, 紧接着下面一个字表示本块申请了多少字节内存. 再下面一个字是类型域, 等于1表示new或malloc()分配的普通块, 2表示CRT分配的供内部使用的块. 0表示已经被用户释放但是还未归还给Win32堆的块通常来说, 新申请的内存块本位置等于1. 最后一块是计数器, 每执行一次内存分配计数器加1.

通过malloc()得到的8字节内存无用内存包围. 这些空内存被填充为0xfd, 当整个内存块被free()时, CRT会检查这些空内存存放的值是否仍然是0xfd. 如果值改变了, 说明程序有错误存在. 真正被使用的8字节内存被初始化为0xcd, 如果你的对象中间出现连续的0xcd, 那么你一定是忘记了初始化一些东西.

当你调用free()释放上述8字节的内存时, CRT首先会用0xdddddddd填充全部48字节的内存块(包括簿记信息), 这样就可以通过检查这块内存的值获知这块内存在释放后是否又被写入过(比如使用野指针写内存).

接下来, CRT通常会调用HeapFree()函数将本内存块归还给win32堆, win32堆会将本内存块填充为0xFEEEFEEE. 注意, CRT并不维护”空闲块列表”, 这些都由HeapFree()来做(译注: 也就是说空闲列表是由Win32 堆来维护的). 但是, 你可以让CRT不把被释放的内存块归还给Win32堆 (译注: 也就是不调用HeapFree()), 方法是将_CRTDBG_DELAY_FREE_MEM_DF传递给_CrtSetDbgFlag(), 这在你跟踪野指针错误时将会派上用场, 在这种情况下, 内存不会被复用, 所以释放过的内存的值必然是0xdddddddd, 除非你对释放过的内存执行了写操作. 你可以调用_CrtCheckMemory()检查释放过的内存是否被篡改.(译注: 这个函数缺省情况下需要显式调用, 你也可以将_CRTDBG_CHECK_ALWAYS_DF传递给_CrtSetDbgFlag(), 这样每次分配和释放内存时都会调用_CrtCheckMemory())

一个例子:

下面是调用p = malloc(8)然后调用free(p)的过程中内存的变化表, malloc(8)返回的指针为0x00321000, 我列出了偏移后的内存值, 以便你找到你自己分配的内存信息.

image