Skip to content

VecReserve

Description

Reserve enough capacity to fit at least n elements without further allocation. Does not change the vector length.

Parameters

Name Direction Description
v in,out Vector handle.
n in Minimum capacity in elements.

Success

Returns true. The vector’s allocated capacity is now at least n elements. The vector length and the values of all existing elements are unchanged.

Failure

Returns false on allocation failure. The vector is unchanged.

Usage example (Cross-references)

Usage examples (Cross-references)
    /// TAGS: Buf, Reserve, Capacity, Allocation
    ///
    #define BufReserve(b, n) VecReserve((b), (n))
    
    ///
    #define VecMustReserve(v, n)                                                                                           \
        do {                                                                                                               \
            if (!VecReserve((v), (n))) {                                                                                   \
                LOG_FATAL("VecReserve failed");                                                                            \
            }                                                                                                              \
        do {                                                                                                               \
            if (!VecReserve((v), (n))) {                                                                                   \
                LOG_FATAL("VecReserve failed");                                                                            \
            }                                                                                                              \
        } while (0)
    /// TAGS: Str, Memory, Reserve
    ///
    #define StrReserve(str, n) VecReserve((str), (n))
    
    ///
                uint16_t capacity = extract_u16(data, offset, data_size);
                capacity          = capacity % 1000; // Limit to reasonable capacity
                VecReserve(vec, capacity);
                break;
            }
                if (*offset + 4 <= data_size) {
                    size_t capacity = extract_u32(data, offset, data_size) % 1000; // Limit to reasonable size
                    VecReserve(vec, capacity);
                }
                break;
                if (*offset + 4 <= data_size) {
                    size_t capacity = extract_u32(data, offset, data_size) % 1000; // Limit to reasonable size
                    VecReserve(vec, capacity);
                }
                break;
        }
        Buf copy = BufInit(alloc);
        if (!VecReserve(&copy, (u64)data_size)) {
            LOG_ERROR("MachoOpenFromMemoryCopy: allocation failed ({} bytes)", (u64)data_size);
            return false;
        }
        Buf copy = BufInit(alloc);
        if (!VecReserve(&copy, (u64)data_size)) {
            LOG_ERROR("ElfOpenFromMemoryCopy: allocation failed ({} bytes)", (u64)data_size);
            return false;
    
        // Ensure we have enough capacity to avoid reallocation during the test
        VecReserve(&vec2, VecLen(&vec2) + 10);
    
        // Try inserting just one element first with fast insert
    
        // Reserve zero capacity
        VecReserve(&vec, 0);
        result = result && (VecCapacity(&vec) == 0);
    
        // Make sure we have enough capacity to avoid reallocation issues
        VecReserve(&vec, 10);
    
        // Create several dummy items to populate the vector
    
        // Reserve more space than needed
        VecReserve(&vec, 100);
    
        // Add some data
    // Test VecReserve function
    bool test_vec_reserve(void) {
        WriteFmt("Testing VecReserve\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        // Reserve space for 50 elements
        VecReserve(&vec, 50);
    
        // Capacity should now be at least 50
    
        // Reserve less space (should be a no-op)
        VecReserve(&vec, 20);
    
        // Capacity should still be at least 50
    
        // Capacity 8 -> 64-byte class (16 int slots). Poison the whole class slot.
        VecReserve(&vec, 8);
        int *base = VecBegin(&vec);
        for (int i = 0; i < 16; i++) {
        // In-place grow to capacity 12 (same 64-byte class). reserve_vec must zero
        // the newly in-range region [8,12).
        VecReserve(&vec, 12);
        VecResize(&vec, 12);
        // abort; the giant realloc fails and reserve reports false. The mutant
        // aborts here.
        bool ok = VecReserve(&vec, (size)-1 - 1);
    
        bool result = (ok == false) && (VecLen(&vec) == 0);
        // allocation, so the mutated MemSet runs off the buffer and faults.
        const size N = 16384;
        VecReserve(&vec, N);
        for (size i = 0; i < N; i++) {
            char c = (char)('a' + (int)(i % 26));
    
        const u32 N = 60000;
        VecReserve(&vec, N);
        for (u32 i = 0; i < N; i++) {
            Wide w = {0};
        IntVec vec = VecInit(&local);
    
        VecReserve(&vec, 64);
        int values[] = {10, 20, 30, 40, 50};
        for (int i = 0; i < 5; i++) {
        IntVec vec = VecInit(&local);
    
        VecReserve(&vec, 50); // length stays 0, capacity > 0, data != NULL
    
        VecMustTryReduceSpace(&vec);
        IntVec vec = VecInit(&local);
    
        VecReserve(&vec, 50); // length stays 0
    
        VecMustTryReduceSpace(&vec);
        IntVec vec = VecInit(&local);
    
        VecReserve(&vec, 100);
        int values[] = {10, 20, 30, 40, 50}; // length 5, deliberately != 42
        for (int i = 0; i < 5; i++) {
        // VecReserve validates first; with n == 0 it would otherwise be a
        // no-op, so the only observable effect is the structural abort.
        VecReserve(&vec, 0);
    
        // Unreachable on real code: the structural validator LOG_FATALs above.
    // wraps to a small allocation and later element writes run off the buffer.
    bool test_vec_reserve_capacity_overflow_aborts(void) {
        WriteFmt("Testing VecReserve capacity*item_size overflow aborts\n");
    
        DefaultAllocator alloc = DefaultAllocatorInit();
        // (size)1<<43 * 2^21 == 2^64 -> wraps past `size`. Well under the
        // reserve_pow2 2^63 cap, and VecReserve hands `n` straight through.
        VecReserve(&vec, (size)1 << 43);
    
        // Unreachable: the guard LOG_FATALs above.
        IntVec vec = VecInit(&alloc);
    
        VecReserve(&vec, 8);
        for (int i = 0; i < 8; i++) {
            VecPushBackR(&vec, i);
        IntVec vec = VecInit(&alloc);
    
        VecReserve(&vec, 10); // exact, non-power-of-2 capacity
        for (int i = 0; i < 5; i++) {
            VecPushBackR(&vec, i);
    
        U64Vec vec = VecInit(&alloc);
        VecReserve(&vec, 16);
        u64 originals[] = {10, 20, 30};
        VecPushBackArrR(&vec, originals, 3);
    
        U64Vec vec = VecInit(&alloc);
        VecReserve(&vec, 16);
        u64 originals[] = {11, 22, 33};
        VecPushBackArrR(&vec, originals, 3);
        TrackVec vec    = make_track_vec(tags, 3);
    
        VecReserve(&vec, 80); // give slots room so a runaway rollback stays in-bounds
    
        // Insert 1 item at the front; copy_init fails immediately (index 0).
        int      tags[] = {1, 2, 3};
        TrackVec vec    = make_track_vec(tags, 3);
        VecReserve(&vec, 32);
    
        // Append 3 items at the end; item 2 (0-based) fails -> inserted_count==2.
        int      tags[] = {1, 2, 3};
        TrackVec vec    = make_track_vec(tags, 3);
        VecReserve(&vec, 32);
    
        // Append 2 items; item 1 fails -> inserted_count == 1.
        int      tags[] = {1, 2, 3};
        TrackVec vec    = make_track_vec(tags, 3);
        VecReserve(&vec, 32);
    
        // Append 2 items; item 1 fails -> inserted_count == 1.
        int      tags[] = {1, 2, 3};
        TrackVec vec    = make_track_vec(tags, 3);
        VecReserve(&vec, 32);
    
        // Append 3 items; item 2 fails -> inserted_count == 2.
        int      tags[] = {1}; // single existing element 'A' at slot 0
        TrackVec vec    = make_track_vec(tags, 1);
        VecReserve(&vec, 32);
    
        // Append (idx == length == 1) 3 items; item 2 fails -> inserted_count == 2.
        int      tags[] = {1, 2, 3};
        TrackVec vec    = make_track_vec(tags, 3);
        VecReserve(&vec, 32);
    
        // Append 2 items; item 1 fails -> exactly 1 inited item.
        int      tags[] = {1, 2, 3}; // A,B,C
        TrackVec vec    = make_track_vec(tags, 3);
        VecReserve(&vec, 32);
    
        // Insert 1 item at idx 1; copy_init fails immediately (inserted_count == 0).
        int      tags[] = {1, 2, 3};
        TrackVec vec    = make_track_vec(tags, 3);
        VecReserve(&vec, 32);
    
        reset_tracking(0);
        int      tags[] = {1, 2, 3};
        TrackVec vec    = make_track_vec(tags, 3);
        VecReserve(&vec, 32);
    
        reset_tracking(0);
Last updated on