Как найти память, используемую любым объектом - PullRequest
20 голосов
/ 29 января 2010
class Help
{
public:
        Help();
        ~Help();

        typedef std::set<string> Terms;
        typedef std::map<string, std::pair<int,Terms> > TermMap;
        typedef std::multimap<int, string, greater<int> > TermsMap;

private:

        TermMap  terms;
        TermsMap    termsMap;
};

Как найти память, используемую (в байтах) объектами term и termsMap. У нас есть какая-нибудь библиотека?

Ответы [ 5 ]

13 голосов
/ 29 января 2010

Если вы ищете полное использование памяти объектом, это не может быть решено вообще в C ++ - хотя мы можем получить размер самого экземпляра через sizeof(), объект всегда может динамически распределять память как необходимо.

Если вы можете узнать, насколько велик отдельный элемент в контейнере, вы можете получить нижнюю границу:

size = sizeof(map<type>) + sum_of_element_sizes;

Имейте в виду, что контейнеры могут по-прежнему выделять дополнительную память в качестве детали реализации, а для таких контейнеров, как vector и string, вы должны проверить для выделенного размера .

8 голосов
/ 29 января 2010

Как мы можем найти используемую память (в байт) по сроку объектов и termsMap. У нас есть какая-нибудь библиотека?

Вы должны использовать свой собственный тип распределителя.

typedef std::set<string, 
    your_allocator_1_that_can_count_memory_consumption_t> Terms;

typedef std::map<string, std::pair<int,Terms>,
    your_allocator_2_that_can_count_memory_consumption_t> TermMap;

typedef std::multimap<int, string, greater<int>, 
    your_allocator_3_that_can_count_memory_consumption_t> TermsMap;

Я еще не проверил эту идею для std :: string, поэтому, если это трудно реализовать, просто используйте свой собственный класс fixed_string, который просто оборачивает char s [max-string-lenght].

А когда вам нужно, чтобы в вашей программе выяснилось потребление памяти, просто получите его из your_allocator_1_that_can_counts_memory_consumption_t, your_allocator_2_that_can_counts_memory_consumption_t, your_allocator_3_that_can_counts_memory_consumption_t.

Отредактировано

Для UncleBens я хочу уточнить мою точку зрения.

Насколько я понимаю вопрос об ARV, необходимо знать, сколько памяти выделено для set :: set и std :: map, включая всю память, выделенную для элементов набора и карты. Так что это не просто sizeof (условия).

Так что я просто предложил очень простой распределитель. Не вдаваясь в подробности, это может выглядеть так:

template <class T>
class your_allocator_1_that_can_counts_memory_consumption_t {
public:
   // interfaces that are required by the standart
private:
   std::allocator<T> std_allocator_;
   // here you need to put your variable to count bytes
   size_t globale_variable_for_allocator_1_to_count_bytes_;
};

Этот распределитель просто подсчитывает количество выделенных и освобожденных байтов, а для реального распределения и освобождения используется его член std_allocator_. Мне может понадобиться отладить его в gdb, чтобы установить точку останова для malloc () и free (), чтобы убедиться, что каждое выделение и освобождение фактически проходят через мой распределитель.

Буду признателен, если вы укажете мне на некоторые проблемы с этой идеей, поскольку я уже реализовал ее в своей программе, работающей на Windows, Linux и HP-UX, и я просто спрашиваю свои распределители, чтобы узнать, сколько памяти у каждого из моих контейнеров использовать.

7 голосов
/ 29 января 2010

Краткий ответ: Нет

Длинный ответ:
-> Основной объект да. sizeof (), но это полезно только для ограниченных вещей.
-> Контейнер и содержащиеся в нем элементы: NO

Если вы делаете предположения о структурах, использованных для реализации этих объектов, вы можете оценить их. Но даже это не очень полезно (кроме очень специфического случая вектора).

Разработчики STL сознательно не определили структуры данных, которые должны использоваться этими контейнерами. Для этого есть несколько причин, но одна из них (на мой взгляд) состоит в том, чтобы не давать людям делать предположения о внутренних элементах и, таким образом, пытаться делать глупости, не связанные с интерфейсом.

Итак, вопрос сводится к тому, зачем вам знать размер?
Вам действительно нужно знать размер (маловероятно, но возможно).

Или есть задача, которую вы пытаетесь достичь там, где, по вашему мнению, вам нужен размер?

1 голос
/ 29 января 2010

Если вы ищете реальный блок памяти, числовое значение указателя на него должно быть именно таким.(Затем просто добавьте количество байтов, и у вас будет конец блока).

0 голосов
/ 29 января 2010

оператор sizeof() должен сделать это:

size_t bytes = sizeof(Help::TermMap);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...