First, declare that this is not because I am angry, it is not because I think there is a lot of cattle, nothing to have anything to the people mentioned in the article (in fact, these are people I have more worship). Just want to say, as long as people may make mistakes, I will never lose the courage of the authority. By the way, responding from the side, Mikeczy is the evaluation of my evaluation, he said "The fool of the rabies", don't move, use the word "refuted". "I may not have a mistake, please also ask Fangjia ax.
One: Mr. Jie's masterpiece "STL source code analysis", there is such a sentence in page 99: "In other words, when the guest calls distance () and uses Output Iterators or Forward Iterators or Bidirectional Iterators, they will transfer the call. The __distance () function of the INPUT ITERATOR. "This sentence should be wrong, because Output Iterators and Input Iterator have no relationships inherited, so how can they not
__distance (__first, __last, output_iterator_tag) derived to call
__distance (__ number, __last, input_iterator_tag). I don't know if I'm thinking?
Second: Feng Yuan is the author of "Windows Graphics Programming", because the book is the GDI module, some may have not read. Of course, those who read through should have a feeling of sighing. However, when the first chapter tells the use of modifications to guide the export table to hook the function, the code given by the code is like this:
// Find the entry with the function name
For (unsigned i = 0; i
IF (stricmp (pprocname, rva2ptr (pnames [i])) == 0)
{
// Get the corresponding Ordinal
ORD = Pexport-> Base Pords [i];
Break;
}
For the following explanations, I will make this simple description. In this code, PEXPORT points to the derived table of the module, ie the pointer to the image_export_directory structure, and PPROCNAME is the name of the API function to be mounted, PNAMES This is the actual address of the member variable addressOfNames of Image_export_Directory. Address. RVA2PTR is a function that converts the RVA address to a real address. It can be seen that this code is the number of orders corresponding to the intention of the function. However, there is a small problem with this, and the termination conditions of the cycle have problems, at least logically wrong. PEXPORT-> addressofnames is a RVA, i is less than a RVA. It is meaningless, although this RVA is usually large enough, so there is a problem with the program running. In fact, I
Its three: Although everyone has a certain counterversion to Microsoft, Microsoft's products have indeed exposed some problems, but we have to admit that his programmer team is top. Then let's talk about Microsoft's Cash Tree Word, in Word, you can choose the format from the menu, choose the background, then choose the watermark, then specify the corresponding text, this will join the watermark such as company secrets in your document. . Can Microsoft's implementation? You draw a box in the document or import a graphic you will know, and the watermark is completely covered. Company confidence also turns into a company secret one. In fact, this problem is really easy to solve, just turn the text to the path, and make sure the function of the output watermark is always called when the header is returned. If I didn't make a mistake, Microsoft was in the BEZIER curve plus filling hard, and the timing of the added watermark was not good, it was really a "cattle". Its four tells the famous SGI STL. Before going down, let's see the program. This program is very simple, just under the Windows operating system, enumerate the system default heap. Finally, the information of each block in the heap and the total TOTALSIZE and FRESIZE of the entire pile.
#include
#include
#include
#include
#include
Using namespace std;
Typedef vector
Typedef deve
Int main (int Argc, char * argv [])
{
Handle hsnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPHEAPLIST,
GetCurrentProcessId ());
Heaplist32 Heaplist32;
Heaplist32.dwsize = sizeof (Heaplist32);
Bool Bret = Heap32ListFirst (HSnapshot, & Heaplist32);
DINT UI;
For (int i = 0; i <4096; i)
{
Ui.push_back (1);
}
Ui.clear ();
IF (BRET)
{
HeapenTry32 HE32;
DWORD TOTALSIZE = 0, FREESIZE = 0;
HE32.dwsize = sizeof (HeaPENTRY32);
Heap32First (& HE32, Heaplist32.th32Processid, Heaplist32.th32heapid);
IF (he32.dwflags & lf32_free)
FreeSize = he32.dwblocksize;
Totalsize = he32.dwblocksize;
COUT << "The Information of First Block:" << "blocksize:" << he32.dwblocksize << "/ t address:" << (long) he32.dwaddress << endl;
While (HEAP32NEXT (& HE32))
{
COUT << "The Information of Block:" << "blocksize:" << He32.dwblocksize << "/ t address:" << (long) he32.dwaddress << Endl; Totalsize = he32.dwblocksize;
IF (he32.dwflags & lf32_free)
FreeSize = he32.dwblocksize;
}
Cout << "The Total Size of the Heap IS: << Totalsize << Endl;
Cout << "The Free Size of the Heap IS: << FreeSize << Endl;
Cout << "The committed size of the heap is:" <"<< (Totalsize-freesize) << Endl;
}
Return 0;
}
Let's run this program in SGI STL. You will be surprised to find out that the UI.clear () result is the same, the results on my machine are as follows:
The Information of First Block: Blocksize: 16836 Address: 7143544
The Information of Block: BlockSize: 3008 Address: 7160384
The Information of Block: Blocksize: 5440 Address: 7163396
The Information of Block: BlockSize: 5776 Address: 7168840
The Information of Block: Blocksize: 6128 Address: 7174620
The Information of Block: Blocksize: 1312 Address: 7180752
The Information of Block: Blocksize: 4144 Address: 7182068
The Information of Block: BlockSize: 1005780 Address: 7186224
The Information of Block: Blocksize: 0 Address: 8192008
The Information of Block: Blocksize: 320 Address: 8192012
The Information of Block: Blocksize: 2096 Address: 8192336
The Information of Block: Blocksize: 1328 Address: 8194436
The Information of Block: Blocksize: 316 Address: 8195776
The Total Size of The Heap IS: 1052484
The Free Size of the Heap IS: 1006096
THE committed size of the heap is: 46388
The strange thing is that the last line is in the last line. After the truth calls clear (), the poor space occupied by the UI should be released (don't forget the internal container to allocate memory), the result of this two times will be output. One of the results in the result should not be the same. If you try further, put the definition of the UI and the operation of the PUSH_BACK in another function, so that the UI is automatically analyzed, you will get the substantially the same result, the pin space occupied by the UI is not released. This means that memory is "leak" in some specific case (which is different from the usual memory leakage). We do some further tests, replace SGI STL to the STL of VC. You will find that the results are fundamentally different from the SGI STL. In executing the UI.clear () or the destructor is called, the process default heap is called to the UI for PUSH_BACK. What is the reason? If you read the source code of SGI STL and carefully analyze the implementation of the SGI to the dispenser (Note 1), you will find that SGI STL uses two different memory allocation mechanisms for both situations in the default. . If the memory block you assign is greater than 128 bytes, the dispenser is allocated directly with Malloc, otherwise a mechanism called Memory Pool will be enabled, and the release of memory in this mechanism is equivalent to the memory. Back to Memory Pool, not true to the system. Since the SGI STL does not release or dynamically reduce the memory in Memory Pool, the memory in the MEMORY POOL can only be released as the process is released. Therefore, the above situation will occur. Since SGI STL decides whether to enable MEMORY POOL mechanisms in _USE_Malloc (STLP_USE_MALLOC) macro we can try again on the basis of defining this macro. You will find that the memory occupied by the UI container is released. Perhaps Memory Pool technology will bring a very big income for the program in a particular situation, but under the Windows platform, because he may lead to the hiddenness of the reaches, I recommend it carefully (especially in the service process. This impact of this memory consumption on the system is very huge).
I have to repeat the opening of the opening, people are a very easy to make mistakes, very unfortunately, the cattle is also a person, but less makes mistakes. Similarly, I am not a cow, I don't dare to affirm that all of my text is all right. I sincerely hope that everyone will give criticism and finger. God may have, but not around us, so do you want to lose your courage.
Note 1: The teacher has a detailed analysis in the book "STL source code analysis".
Note 2: The third edition of "The C Programming Language has a simple implementation.
Note 3: It is best to ensure that the space occupied by the container should not exceed 1m, because the process defaults to 1m, more than 1M, the system will expand the process default heap, which may cause statistics to appear confusion. For example, the more you can use, the more free.
Note 4: The result given the HEAP code given corresponds to the 98 system. 2000 If you want to see this change, you have to enumerate all stacks in the process. Because the 2000 C runtime library does not use the process default heap.