Home > OS >  sizeof(std::vector<T>) v/s sizeof(std::array<T, N>)
sizeof(std::vector<T>) v/s sizeof(std::array<T, N>)

Time:03-12

I'm confused between the sizeof(std::vector<T>) and sizeof(std::array<T, N>).

int main(int argc, char const *argv[]) {
    std::vector<int64_t> vec_1(2);
    std::cout << sizeof(vec_1) << std::endl;  // 24

    std::vector<int64_t> vec_2(5);
    std::cout << sizeof(vec_2) << std::endl;  // 24

    std::array<int64_t, 2> arr_1;
    std::cout << sizeof(arr_1) << std::endl;  // 16

    std::array<int64_t, 5> arr_2;
    std::cout << sizeof(arr_2) << std::endl;  // 40

    return 0;
}

As can be seen above sizeof(std::vector<T>) remains constant irrespective of a number of elements. However, that's not the case for sizeof(std::array<T, N>). Why? Both of them are STL containers.

Even for all the other STL containers like std::map<T1, T2>, std::unordered_map<T1, T2>, etc, I noticed that the output of sizeof remains constant irrespective of a total number of elements. Then why does for std::array<T, N>, it changes based on the number of elements? If that's how it's designed then why so?

CodePudding user response:

Because the size of an array depends on its number of elements, but the size of a pointer doesn't depend on the number of elements in the array it points to.

std::array is a wrapper for a C-style fixed array. It directly contains its elements. You can think of it as looking something like this:

template <typename T, size_t N>
class array
{
    T arr[N];

    // member functions
};

Since sizeof(T[N]) varies with N, so too will sizeof(std::array<T, N>).


std::vector, on the other hand, is a wrapper for a dynamically allocated array. It just holds a pointer to its array, allocating the actual array at runtime elsewhere in memory. That means it looks something like this:

template <typename T, /* other stuff */>
class vector
{
    T* arr;
    size_t count;

    // member functions and such
};

Since neither sizeof(T*) nor sizeof(size_t) vary with count, sizeof(std::vector<T>) is constant.

CodePudding user response:

std::array doesn't let you add more elements. It's a fixed-size array whose size is known at compile-time, so the array is stored directly. This prevents a needless indirection when accessing the data—it's right there. It also has other benefits that bring it closer to a traditional C array.

std::vector and the other containers require an indirection, so the size you see includes a pointer used for that indirection. Eventually, your vector's going to hit its capacity and need to allocate more memory. You can't do that while keeping the data within the vector object itself—the object size must be known at compile-time so that the compiler knows how much stack space to allocate for it. You could have a maximum size and put that many elements into the container object itself, but that's a different container that doesn't exist in the standard library at this time.

  • Related