Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

An experiment to understand ways of copying C arrays to vector



  • I found out today that most (a lot of?) std containers can accept raw pointers.

    Here is the code I tested with:

    {
            using namespace std;
    
            auto loop = [](const char* name, vector<int>& v){
                qInfo() << name;
                qInfo() << v.size() << v.capacity();
                qInfo() << v;
            };
    
            int arr[] = {0,1,2,3,4,5,6,7,8,9};
            size_t arrsize = sizeof(arr)/sizeof(*arr);
    
            // at initialization
            vector<int> vec(arr, arr+arrsize);
            loop("vec", vec);
    
            // resizes vector and assigns values
            vector<int> vec2;
            vec2.assign(arr, arr+arrsize);
            loop("vec2", vec2);
    
            // using copy
            vector<int> vec3;
            copy(arr, arr+arrsize, back_inserter(vec3));
            loop("vec3", vec3);
    
            // using copy with reserve
            vector<int> vec4;
            vec4.reserve(arrsize);
            copy(arr, arr+arrsize, back_inserter(vec4));
            loop("vec4", vec4);
        }
    

    The results:

    vec
    10 10
    std::vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    vec2
    10 10
    std::vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    vec3
    10 16
    std::vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    vec4
    10 10
    std::vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    

    I am particularly fascinated by what happened to vec3. Some kind of resize to multiple of 8 on insert? Kinda neat. That would mean that the vector resized twice if that is true.


  • Moderators

    @fcarney said in An experiment to understand ways of copying C arrays to vector:

    I found out today that most (a lot of?) std containers can accept raw pointers.

    These are called range constructors. They actually accept iterators like vec.begin(), vec.end(). It just so happens that vector iterators are implemented as raw pointers.

    In contrast, a linked list's iterators are not raw pointers.

    I am particularly fascinated by what happened to vec3. Some kind of resize to multiple of 8 on insert? Kinda neat. That would mean that the vector resized twice if that is true.

    No resizing was done. The system just "prepared" more memory than necessary during initialization. This allows you to append a few more elements without reallocating memory: http://www.cplusplus.com/reference/vector/vector/capacity/ ( EDIT: Actually, I can't tell if multiple allocations were done or not )



  • @JKSH said in An experiment to understand ways of copying C arrays to vector:

    No resizing was done.

            // using copy
            vector<int> vec3;
            qInfo() << vec3.capacity();
            copy(arr, arr+arrsize, back_inserter(vec3));
            loop("vec3", vec3);
    

    Output:

    0
    vec3
    10 16
    std::vector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    

    Maybe I said the wrong term. A reserve was done.


Log in to reply