размер двойных и плавающих объектов в списке равен? - PullRequest
12 голосов
/ 12 декабря 2011

Мне интересно, равны ли размеры объектов типа float и double с точки зрения std :: list?

Я выделил 5 миллионов объектов Real (псевдоним с плавающей запятой или двойных) в std :: list и использовал Valgrind для мониторинга использования памяти.

в обоих случаях используемая память одинакова, хотя размер 'double' (8 байт) в два раза больше, чем у объекта 'float' (4 байта)!

Кстати, когда я выделяю память для того же количества объектов, используя оператор 'new', использование памяти двойным массивом вдвое превышает использование массива float, что кажется правильным. Я ожидал того же, используя std :: list.

Я использую gcc 4.6.2 в Fedora 16.x86_64.

Любая идея помочь мне понять, что тайна ценится.

вот код, который я написал для теста

#include <iostream>
#include <list>

typedef double Real;

int main(int argc, char** argv)
{
    std::list<Real> pts;
    int k;

    int npts = 5000000; // 5 mil

    std::cout << "sizeof(Real): " << sizeof(Real) << std::endl;
    for(k=0; k < npts;++k)
        pts.push_back(1.0);

    return 0;

}

если я определяю Real <- удвоить вывод Valgrind равным </p>

==15335== Memcheck, a memory error detector
==15335== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==15335== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==15335== Command: /home/soheil/Workspace/tbin/test_memory_usage
==15335== 
sizeof(Real): 8
==15335== 
==15335== HEAP SUMMARY:
==15335==     in use at exit: 616 bytes in 6 blocks
==15335==   total heap usage: 5,000,053 allocs, 5,000,047 frees, 120,015,245 bytes allocated
==15335== 
==15335== LEAK SUMMARY:
==15335==    definitely lost: 0 bytes in 0 blocks
==15335==    indirectly lost: 0 bytes in 0 blocks
==15335==      possibly lost: 0 bytes in 0 blocks
==15335==    still reachable: 616 bytes in 6 blocks
==15335==         suppressed: 0 bytes in 0 blocks
==15335== Rerun with --leak-check=full to see details of leaked memory
==15335== 
==15335== For counts of detected and suppressed errors, rerun with: -v
==15335== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

если я определяю Real <- float, то вывод Valgrind равен </p>

==15252== Memcheck, a memory error detector
==15252== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
==15252== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
==15252== Command: /home/soheil/Workspace/tbin/test_memory_usage
==15252== 
sizeof(Real): 4
==15252== 
==15252== HEAP SUMMARY:
==15252==     in use at exit: 616 bytes in 6 blocks
==15252==   total heap usage: 5,000,053 allocs, 5,000,047 frees, 120,015,245 bytes allocated
==15252== 
==15252== LEAK SUMMARY:
==15252==    definitely lost: 0 bytes in 0 blocks
==15252==    indirectly lost: 0 bytes in 0 blocks
==15252==      possibly lost: 0 bytes in 0 blocks
==15252==    still reachable: 616 bytes in 6 blocks
==15252==         suppressed: 0 bytes in 0 blocks
==15252== Rerun with --leak-check=full to see details of leaked memory
==15252== 
==15252== For counts of detected and suppressed errors, rerun with: -v
==15252== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

1 Ответ

10 голосов
/ 12 декабря 2011

Каждый элемент в std::list<T> является узлом связанного списка, поэтому это структура, содержащая два указателя, а также данные полезной нагрузки типа T. Например, для GCC 4.1.2 это выглядит следующим образом:

  struct _List_node_base
  {
    _List_node_base* _M_next;
    _List_node_base* _M_prev;

    // *** Non-virtual member functions ***
  };

  template<typename _Tp>
    struct _List_node : public _List_node_base
    {
      _Tp _M_data;
    };

Выделенный размер будет размером этой структуры; если T достаточно мало, то, возможно, вы видите цифры, в которых преобладают структурные отступы.

Таким образом, в определении GCC это два 64-битных указателя (16 байтов), плюс 4 или 8 байтов T, дополняемые до 8 байтов, итого 24 байта, что соответствует тому, что вы измеряете.

Чтобы проверить теорию, попробуйте изменить Real на float[2] или double[2].

...