Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

size of double and float objects in a list are equal?

I am wondering if the size of float and double objects are equal from std::list point of view?

I've allocated 5-million Real(alias float or double) objects in a std::list and used Valgrind to monitor memory usage.

in both cases the used memory is equal although the size of a 'double' (8 bytes) is double the size if a 'float' object (4 bytes)!

Btw, when I allocate memory for the same amount of objects using 'new' operator, the memory usage of the double array is double the usage of the float array, which seems about right. I was expecting the same using std::list too.

I am using gcc 4.6.2, on Fedora 16.x86_64.

Any idea to help me figure the mystery is appreciated.

here is the code I wrote for test

#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;

}

if I define Real <- double the Valgrind output is

==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)

if I define Real <- float the Valgrind output is

==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)
like image 858
Soheil Sotoodeh Avatar asked Dec 12 '11 14:12

Soheil Sotoodeh


People also ask

What is the size of float and double in Java?

Size: Float is of size 32 bits while double is of size 64 bits. Hence, double can handle much bigger fractional numbers than float. They differ in the allocation of bits for the representation of the number.

What is the maximum size of a double float variable?

C) 8 bytes will be the maximum size of a double variable.


1 Answers

Each element in a std::list<T> is a linked-list node, so it's a struct containing two pointers, as well as the payload data of type T. For instance, for GCC 4.1.2, it's as follows:

  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;
    };

The size allocated will be the size of that struct; if T is small enough then you may be seeing the figures dominated by struct padding.

So with the GCC definition, that's two 64-bit pointers (so 16 bytes), plus 4 or 8 bytes T, padded up to 8 bytes, so 24 bytes in total, which matches what you're measuring.

To test the theory, try changing Real to be float[2] or double[2].

like image 128
Oliver Charlesworth Avatar answered Oct 19 '22 00:10

Oliver Charlesworth