Memory leak with dynamic array

bearophile bearophileHUGS at lycos.com
Sun Apr 11 18:25:00 PDT 2010


A third uglier D version, this is a bit faster than the C++ version. With few experiments I've seen that the second D version was slower than the C++ code because dmd missed the inlining of the opOpAssign and because it contaned the if(capacity<BIG_MEM) test too.

LDC can surely inline the method in a situation like that. But the BIG_MEM test was something I have added to reduce memory usage for very large vectors. I don't know if the C++ implementation has something similar.


// Third D version
import std.stdio: printf;
import std.c.stdlib: malloc, realloc, free;

struct Vector(T) {
    enum double FAST_GROW = 2;
    enum double SLOW_GROW = 1.3;
    enum int STARTING_SIZE = 4;
    enum int BIG_MEM = (1 << 27) / T.sizeof;

    T* ptr;
    int length, capacity;

    ~this() {
        free(ptr);
        ptr = null;
        length = 0;
        capacity = 0;
    }
}

void main() {
    alias double T;
    enum int N = 5_000_000;
    enum int NLOOPS = 100;
    Vector!T arr;

    foreach (i; 0 .. NLOOPS) {
        arr.length = 0;
        printf("Array capacity = %d\n", arr.capacity);

        foreach (uint j; 0 .. N) {
            if (arr.length >= arr.capacity) {
                int new_capacity = arr.capacity ? cast(int)(arr.capacity * arr.FAST_GROW) : arr.STARTING_SIZE;
                arr.ptr = cast(T*)realloc(arr.ptr, new_capacity * T.sizeof);
                assert(arr.ptr);
                arr.capacity = new_capacity;
            }

            arr.ptr[arr.length] = j;
            arr.length++;
        }

        printf("At iteration %u, x has %u elements.\n", i, arr.length);
    }
}

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list