Hi,
I have some questions on vector.
Please consider the code below. I use g++ compiler on Linux.

#include<iostream>
#include<vector>
using namespace std;
class Sampler {
      int a;
      int b;
};

int main()
{
         vector <int> vec1;
         vector<float> vec2;
         vector<Sampler> vec3;
         cout << sizeof(vec1) << " " << sizeof(vec2) 
                  << sizeof(vec3) << endl;
         
         return 0;
}

1. when I try sizeof() with vector objects of different types, the size is shown as 12 bytes. What surprises me even further is, even after pushing an element in to the vector, sizeof shows the same size.
Could somebody please explain why? Does the compiler not discriminate the type of data a vector holds?

2. In the above code snippet, when I define class Sampler as a local class, g++ shoots an error. Why is it that compiler works fine with vector vec3's declaration when class Sampler is global and shoots an error when Sampler is local to main?

Thanks in advance.

Dani AI

Generated

A few concise clarifications that follow from the examples and replies already in the thread.

As noticed, the 12 bytes come from the vector object itself — not the elements it holds. To expand on that: most standard-library implementations (including libstdc++) store three pointer-sized members inside a std::vector (begin, end, end_of_storage). On a 32-bit build that is 3 4 = 12 bytes; on a 64-bit build it will commonly be 3 8 = 24 bytes. Pushing elements reallocates or writes into the heap buffer the vector manages; it does not change the size of the container object that sizeof reports. This is why sizeof(vec) remains constant regardless of push_back.

To get a practical idea of runtime memory use, combine the container object plus its allocated block:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> v;
    v.reserve(100);
    std::cout << "sizeof(v): " << sizeof(v) << "\n";
    std::cout << "capacity(): " << v.capacity() << "\n";
    std::cout << "approx heap bytes: " << v.capacity() * sizeof(int) << "\n";
}

That gives a reasonable estimate (allocator overhead and alignment can add extra bytes).

Regarding the local-class error: as pointed out, the C++ language requires template arguments to be types with linkage; local classes (classes defined inside a function) have no linkage and therefore cannot be used as template parameters in strictly conforming implementations. GCC enforces that rule; some compilers historically accept it as an extension. For details see the cppreference note on local classes: Local classes. The usual fix is to move Sampler to namespace scope (or use a type-erasure approach such as std::any or a polymorphic base with external linkage) rather than relying on compiler extensions.

Quick caution: sizeof answers "how big is the object representation" — it is not a measure of heap usage. Use capacity() and allocator-aware profiling tools (Valgrind/Massif, allocator hooks) for accurate memory profiling.

Recommended Answers

All 4 Replies

Member Avatar for Member #248612

1. in short: sizeof() returns the sum of the sizes of the member variables. One of these member variables points to the allocated space used for storing your data.

2. can't help you here, i'm using VS2008

The std::vectors uses heap storage (dynamic memory management). When you declare an vector, vec1, all you do is instantiate a vector object. When you push_back elements in a vector, it automatically manages it and store it somewhere in the memory and stores pointers to those object with it. So now when you say sizeof(vec), you are actually getting the size of the vector object and not of the elements inside them.
Hence, size of vector is constant (which differs from implementation to implementation) no matter how many element you push.
You would never need to bother about those.

Even now, if you are not clear, consider the following class:

class myVector
{
    private:
    int* p;
    public:
    myVector(int size)
    {
        int* p= new int[size];
    }
};

Now, no matter if you print sizeof(myVector(100)) or sizeof(myVector(500), the system will print the same value.
Why? Because sizeof() will yeild sizeof(int*) that is the size of a pointer to int [1].

[1] This is actually not true in general. sizeof() operator will actually yield a value which would be at least the value of the sum of the size of all its member. It may yield more than that too, in case polymorphism is involved, but we can leave the details here.

Edit1: To jencas: Read my foot note above. sizeof can also yield a value more than the individual members.

Edit2: To mrinal.s2008: Regarding your second problem, g++ is correct. According the the ISO C++, the template argument should have external linkage. Although, this rule is likely to be changed soon. Read http://gcc.gnu.org/ml/gcc/2009-04/msg00510.html

2. In the above code snippet, when I define class Sampler as a local class, g++ shoots an error. Why is it that compiler works fine with vector vec3's declaration when class Sampler is global and shoots an error when Sampler is local to main?

It is just one of those restrictions in the standard. Template type arguments cannot refer to a type without linkage, or a pointer to a type without linkage, and local class definitions match that restriction.

You can read the details in , section 14.3.1.2.

Member Avatar for Member #248612

Edit1: To jencas: Read my foot note above. sizeof can also yield a value more than the individual members.

That's why I wrote "in short". Not only polymorphism can increase the size, memory boundary alignment can too.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.