-1

Имея этот простой код в C++:Распределение памяти в ОС

#include <iostream> 
#include <memory> 
#include <vector> 
using namespace std; 

class Empty{}; 

int main() { 
    array<unique_ptr<Empty>, 1024> empties; 

    for(size_t i =0; i < 1024; i++){ 
     empties[i] = make_unique<Empty>(); 
    } 

    for(auto& element : empties){ 
     cout << "ptr: " << element.get() << endl; 
    } 

    return 0; 
} 

при работе в ideone.com или Windows, мы получаем следующий результат:

ptr: 0x2b601f0c9ca0 
ptr: 0x2b601f0c9cc0 
ptr: 0x2b601f0c9ce0 
ptr: 0x2b601f0c9d00 
ptr: 0x2b601f0c9d20 
ptr: 0x2b601f0c9d40 
ptr: 0x2b601f0c9d60 ... 

Для меня это совершенно странно. какие алгоритмы распределения в ОС или стандартной библиотеке могут привести к тому, что не было выделено по адресу, которое заканчивается числом, отличным от 0?

Причина, по которой я сделал этот эксперимент, заключается в том, что, учитывая, что ОС использует алгоритм buddy, который управляет страницами и запрос на распределение, заставит ОС выделить кусок непрерывной памяти, а затем пару следующих распределений (до истечения выделенной памяти) должны быть выделены довольно близко. Если бы это было так, то, вероятно, проблема с кешем со списками не была бы столь значимой в некоторых случаях, но я получил результаты, которых я не ожидал в любом случае.

Также второе число справа в выделенных узлах является случайным образом. Что может вызвать такое поведение?

+3

Я не знаю, какую ОС вы используете, но по крайней мере Linux выравнивает все распределения кучи до 16 байт. Некоторые хитроумные люди, такие как команда llvm, фактически используют этот факт, чтобы хранить вещи на тех всегда нулевых битах. –

+3

Сама ОС не имеет ничего общего с этим. ОС выделяет страницы, распределитель вашей программы (вероятно, из стандартной библиотеки, с которой вы динамически связаны, которая может поставляться с ОС, но не является самой ОС) подразделяет страницы на выделенные блоки. Возможно, потребуется некоторое пространство для информации отслеживания, выровнять распределения по причинам, связанным с эффективностью/фрагментацией, и т. Д. Наличие пустой стоимости размещения 32 байта не является необоснованным/неслыханным. – ShadowRanger

+0

Даже если структура пуста, она все равно должна иметь размер, который может быть адресуемым. К этому размеру добавятся выравнивание и добавление системных распределителей. –

ответ

-2

Обратите внимание, что печатные указатели неточны, ОС позволяет вам видеть их в качестве последующих указателей, когда они могут быть выделены на совершенно разные страницы.

+0

Зачем им выделяться на разные страницы? – DawidPi

+0

О какой ОС вы говорите? – niceman

+0

ОС Windows, но я думаю, что это было бы и в Linux – DawidPi

-1

Минимальный размер класса в C++ - это один байт, если я правильно помню. Поскольку между классом существует согласованное 32-байтовое расстояние, может оказаться, что это размер вашего пустого класса. Чтобы определить это, попробуйте добавить

std::cout << "Empty class size: " << sizeof(Empty) << std::endl; 

Это, вероятно, не будет 32 байт, а, вероятно, будет некоторое последовательное расстояние между каждым объектом.

Примечание: Вы компилируете это для вас. Это не для меня, потому что пустоты не могут быть неявно инициализированы.

+0

да он делает :) http://ideone.com/9lWs7Z. Не должно быть никаких проблем с инициализацией, поскольку unique_ptr имеет конструктор по умолчанию. – DawidPi

+0

Хммм. Это странно. Используя clang с -std = C++ 14, тогда IDK. – jellyfishcoder

+0

Пожалуйста, обратитесь к данной ссылке в приведенном выше комментарии для подсказки :) – DawidPi