I read this article, and I can not understand some of the techniques. If anyone can, please explain what happens, for example, here:

void FormatNewPage() { void* tmp = GetPage(); // получаем адрес начала блоков памяти head = tmp; // голову на начало блока памяти for(size_t i = 0; i < count-1; i++) { void* next = (char*)tmp + BlockSize; // получаем адрес следующего блока. *(void**)tmp = next; // ?? эта манипуляция мне не понятна tmp = next; // в "текущем" блоке указываем адрес следующего свободного блока } *(void**)tmp = NULL; // последний блок ни на что не указывает - терминируем. } 

The general idea is, of course, understandable - the “markup” of the memory goes, and using the properties of the pointers they make connections — You can say I get a singly linked list of pointers to an array.

But it is not at all clear why such a cast is in the code * (void **), because the type is so void *.

As I understand it, as a result of such a cast * (void **) tmp - the compiler looks at tmp as a dereferenced pointer of type void * —in fact, with my current knowledge — it seems to me that this should not change anything at all. But if you make such a simple experiment (g ++, linux 64bit)

 char arr[]={'a','b','c','d','\0'}; void * vptr = new char[1024*2]; std::cout << vptr << '\n'; // 0x9c9010 std::cout << (void**)vptr << '\n'; // 0x9c9010 std::cout << (void*****)vptr << '\n'; // 0x9c9010 std::cout << *(void**)&vptr << '\n'; // 0x9c9010 std::cout << *(void**)vptr << '\n'; // 0 -- почему так ? memcpy((char*)vptr,arr,sizeof(arr)); // std::cout << *(void**)vptr << '\n'; // 0x64636261 -- почему так ? 

It becomes evident that * (void **) tmp somehow changes the address. As, unfortunately, I can not find information. If anyone knows, explain, or at least give the links something to read.

Studying a code from article, on f-ii

 void* AllocBlock() { if (!head) FormatNewPage(); void* tmp = head; head = *(void**)head; return tmp; } 

It can be concluded that * (void **) head; makes some pointer address increment, but in my experiment this increment turns out to be very huge - and it seems to be significantly beyond the 1024 * 2 area by address arithmetic.

And for some reason I cannot find in any article, and in those books that I read (although there were not so many of them of course) there was no such method of passage to addresses as * (void **) (if this is of course used at all for some passage explicitly or indirectly)

In general, I do not understand. Thank you for your time.

  • one
    ** is a pointer to a pointer. That is, what is located at the address from tmp is also treated as an address, and already at this address a value is searched. - Smithson
  • Smithson, now everything has become clear. Cheto himself not doper. Thank you :) - Ilya Lesnoy

1 answer 1

The issue is resolved, thanks to the user Smithson

** is a pointer to a pointer. That is, what is located at the address from tmp is also interpreted as an address, and already at this address the value is searched.