0

I am having some trouble with memory leak in a class I wrote. First, I measured the virtual memory used, then a run a test sequence and tried to release the memory.
PS.:The main purpose here is to avoid memory leak, so the virtual memory should be freed, but It is not happening.

The result of the test was:

VETOR mem: 7045873664 -> virtual memory used before operation

[1.0000000 2.0000000 3.0000000 4.0000000 ] [1.0000000 2.0000000 3.0000000 4.0000000 ] [2.0000000 4.0000000 6.0000000 8.0000000 ] [3.0000000 5.0000000 7.0000000 9.0000000 ] [0.0000000 0.0000000 0.0000000 0.0000000 ] [30.0000000 ]

VETOR mem: 7077228544 -> virtual memory used after operation

  • this was done in VS2015 com. in Release Mode

The code of test was:

Vector A,B,C;
A = { 1, 2, 3, 4 };
B = A;
A.Print();
B.Print();

for (int i = 0; i < 500000; i++)
{
    C = A + B;
}



C.Print();
(C + 1.0).Print();
(A - B).Print();

(A*B.Transpose()).Print();

A.~Vector();
B.~Vector();
C.~Vector();

The class Vector is describe bellow:

class Vector
{

private:
int size;
long double *p;


public:
Vector()
{
    size = 0;
    p = NULL;
}

~Vector()
{
    if (p != NULL)
    {
        delete[] p;
        p = NULL;
    }
}

Vector(const int r)
{

    if (r > 0)
    {
        size = r;

        p = NULL;
        p = new long double[size];

        for (register int i = 0; i < size; i++)
        {
            //p[i] = new long double[1];
            p[i] = 0.;
        }
    }
}

// construtor cópia      
Vector(const Vector& v)
{
    size = v.size;

    p = NULL;
    p = new long double[size];

    for (register int i = 0; i < size; i++)
    {
        //p[i] = new long double[1];
        p[i] = v.p[i];
    }

}

// Initialize to array
Vector(const long double* a, int n)
{
    size = n;

    p = NULL;
    p = new long double[size];
    for (register int i = 0; i < size; i++)
    {
        //p[i] = new long double[1];
        p[i] = *a++;
    }
}

template <typename T, size_t n>
Vector(const  T(&a)[n])
{
    size = n;

    p = NULL;
    p = new long double[size];

    for (register int i = 0; i < size; i++)
    {
        p[i] = a[i];
    }
}

long double& operator()(const int r)
{
    if (p != NULL && r > 0 && r <= size)
    {
        return p[r - 1];
    }
    else
    {
        throw Exception("Subscript out of range");
    }
}

long double& operator()(const int r) const
{
    if (p != NULL && r > 0 && r <= size)
    {
        return p[r - 1];
    }
    else
    {
        throw Exception("Subscript out of range");
    }
}

// assignment operator

Vector& operator= (const Vector& v)
{
    try
    {
        if (p != NULL)
        {
            delete[] p;
            p = NULL;
        }

        size = v.size;

        if (p == NULL) p = new long double[v.size];

        for (register int i = 0; i < v.size; i++)
        {
            p[i] = v.p[i];
        }
    }
    catch (exception& e)
    {
        cout << "Vector operator=: Standard exception: " << e.what() << endl;
    }
    return *this;
}


template <typename T, size_t n>
Vector& operator= (const T(&a)[n])
{
    if (p != NULL)
    {
        delete[] p;
        p = NULL;
    }


    size = n;

    p = new long double[size];

    for (register int i = 0; i < size; i++)
    {
        p[i] = a[i];
    }

    return *this;
}


Vector& operator= (const long double& k)
{
    try
    {
        if (p != NULL)
        {
            delete[] p;
            p = NULL;
        }

        if (p == NULL)  p = new long double[size];

        for (register int i = 0; i < size; i++)
        {
            // copy the values from the vector v
            //p[i] = new long double[1];
            p[i] = k;
        }
    }
    catch (exception& e)
    {
        cout << "Vector operator=: Standard exception: " << e.what() << endl;
    }
    return *this;
}

friend Vector operator+(const Vector& a, const Vector& b)
{
    Vector Nulo(a.size);
    Nulo = 0.0;

    if (a.size == b.size)
    {
        Vector res(a.size);

        for (register int i = 0; i < a.size; i++)
        {
            res.p[i] = a.p[i] + b.p[i];
        }
        return res;
    }
    else
    {
        throw("Subscript out of range");
    }

    return Nulo;
}

// soma de escalar + vetor : somar a todos os elementos
friend Vector operator+(const long double& a, const Vector& b)
{
    Vector res(b.size);
    Vector Nulo(b.size);

    //res = Vector(b.size);
    //res.size = b.size;
    res = 0.0;

    for (register int i = 0; i < b.size; i++)
    {
        res.p[i] = a + b.p[i];
    }
    return res;
}

// soma de  vetor + escalar : somar a todos os elementos
friend Vector operator+(const Vector& b, const long double& a)
{
    Vector res, Nulo;

    res = Vector(b.size);
    res.size = b.size;
    res = 0.0;

    for (register int i = 0; i < b.size; i++)
    {
        res.p[i] = a + b.p[i];
    }
return res;
    }
}


class Exception
{
public:
    const char* msg;
    Exception(const char* arg)
        : msg(arg)
    {
    }
};
  • you should reduce the code length. and post minimal code. see [mcve]. – apple apple Aug 19 '18 at 02:42
  • Perhaps memory fragmentation? Deleting an object might be freeing a spot on the heap, but that heap may not be able to be released back to the OS. Not sure though. Check out this thread: https://arstechnica.com/civis/viewtopic.php?f=20&t=809735 – Steve Aug 19 '18 at 03:17
  • 2
    The in the code `p=NULL;` then `p = new long double[v.size];` the `p=NULL;` part is totally unnecessary. With that said a modern compiler should optimize it out. – drescherjm Aug 19 '18 at 03:17
  • 5
    How are you measuring the memory usage? Operator `delete` releases the memory as far as your *program* is concerned. That does not necessarily mean the memory is released by your program/process to the host system. – Peter Aug 19 '18 at 03:18
  • `Vector(const int r)` if r <= 0 you don't initialize size or p – drescherjm Aug 19 '18 at 03:20
  • 4
    `for (register int i = 0; i < size; i++)` these days you really don't need to use `register` – drescherjm Aug 19 '18 at 03:23
  • Welcome to Stack Overflow! I edited the code to remove a bunch of unnecessary blank lines that weren't helping. For example, a blank line after a { doesn't help make it clearer and just makes it more necessary to scroll. Kept some that may help. – Brian Carlton Aug 19 '18 at 04:24
  • 2
    You should almost never call destructors explicitly. Certainly not in this program. – n. m. could be an AI Aug 19 '18 at 05:09
  • 2
    `Exception`, `Print`, `operator-`, `Transpose` are not defined anywhere in the posted code, Please post a [mcve]. It looks like memory leaks are not among the (many) flaws of the posted code. Perhaps code that you didn't post contains some. – n. m. could be an AI Aug 19 '18 at 06:02
  • 1
    Unless your compiler is from the 1980s, "register" doesn't do anything. – molbdnilo Aug 19 '18 at 06:03
  • By the way `register` is **not allowed** by the current C++ standard. – n. m. could be an AI Aug 19 '18 at 06:04
  • 4
    Your explicit destructor calls cause undefined behaviour. Consider getting [a decent book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – molbdnilo Aug 19 '18 at 06:06
  • 2
    Looking at the memory usage after a single operation isn't a good way of finding memory leaks. Freed memory isn't necessarily released back to the OS. If you perform multiple operations which should release all of their memory and the memory usage grows over time then you probably have a memory leak. – Alan Birtles Aug 19 '18 at 08:06
  • yeah this stuff is optimized by os. It's just none of your business – Алексей Неудачин Aug 19 '18 at 12:08
  • When I run the looping less times the memory dont increase. – Horacimar Pinheiro Cotrim Aug 20 '18 at 11:24
  • This was a test to understand why my Program is getting stuck after some time of run. I AM doing a fitting of a thermodynamic model parameters with experimental data. When I run the Program Just a once there isnt problem, but to do the fitting operation It get stuck after some looping. – Horacimar Pinheiro Cotrim Aug 20 '18 at 11:36
  • I called destrutor Just to know If the release of memory was happening... – Horacimar Pinheiro Cotrim Aug 20 '18 at 11:38

0 Answers0