Handling arrays of objects in memory

Pages: 12

Hello! I want to understand how dynamic memory allocation works for some code I wrote, so I'll try to describe it in a simple example:

I have 2 simple objects:

1
2
3
4
5
6
7
8
9
10
11
class B
{
    public:
    int myNum;
};

class A
{
    public:
    B* myObj;
};


and my main() looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.
.
.
A* obj1;
A* obj3;

int main()
{
    obj3 = new A[20];
    .
    .
    .
    {
        A* obj2 = new A;
        *obj2->myObj = new B[10];

        obj1 = new A;
        *obj1 = *obj2;
    }
    .
    .
    .
}


obj2 allocated an array of B objects and when it copied its values to obj1 the pointer to that array was passed also. So the 2 objects point to the same array.

When the obj2 leaves its variable scope the memory of that object is freed (if I understand correctly). That means that the array of B objects that was created through obj2 is also deleted and obj1 which is global points to an invalid memory space?

My other question is is there a way to free the memory that the last 15 elements of the obj3 array hold?

closed account (1yR4jE8b)
No, when you explicitly allocate memory with new you must explicitly free it with a call to delete.

When obj2 leaves variable scope, the POINTER is freed, but not what it points TO. So you have a memory leak for your obj2 object. obj2 is also responsible for managing it's own pointer to a section of dynamic memory through myObj, which is also not deleted before obj2 leaves scope. That is another memory leak.
Line 15 has a syntax error:
/***/obj2->myObj = new B[10];

When the obj2 leaves its variable scope the memory of that object is freed (if I understand correctly). That means that the array of B objects that was created through obj2 is also deleted and obj1 which is global points to an invalid memory space?
No. Neither class defines a destructor, and the destructor automatically defined by the compiler doesn't delete member pointers, partly because of this, partly because the pointer might have been created by a different function, such as malloc().

My other question is is there a way to free the memory that the last 15 elements of the obj3 array hold?
No. When you allocate an array, you allocate a single memory object (a memory object is an array of n raw bytes. It's what you get by calling malloc(n)). Memory objects are indivisible; either you completely destroy one, or not at all. You can't destroy only part of one. In this sense, they're analogous to C++ objects. You can't create an object and then destruct half of its members when you don't need need them anymore.
Last edited on
When obj2 leaves the scope, only its members will be freed, not the objects they may point to. So the pointer obj2->myObj will be destroyed but not the array that it points to. So obj1 will still contain a valid pointer.
closed account (1yR4jE8b)
Forget everything I wrote in my previous post. There is no memory leak in this program (technically, because obj1 and 3 are freed by the OS when main returns) and obj1 points to valid memory because obj2 is not deleted.

I really should read these things more carefully before I post lol. Then again, I don't throw around pointers like water balloons when I program, so when I see jumbles like this I tend to not be able to follow it.
closed account (1yR4jE8b)
Forget everything I wrote in my previous post. There is no memory leak in this program (technically, because obj1 and 3 are freed by the OS when main returns) and obj1 points to valid memory because obj2 is not deleted.

I really should read these things more carefully before I post lol. Then again, I don't throw around pointers like water balloons when I program, so when I see jumbles like this I tend to not be able to follow it.
darkestfright wrote:
There is no memory leak in this program (technically, because obj1 and 3 are freed by the OS when main returns)

It's still a memory leak if the OS has to clean it up.
closed account (1yR4jE8b)
I agree, but in this particular case it's so trivial, no need to even worry about it.
Thank you all for your responses!

That's what I pretty much had in mind but my program behaves differently. What I do is this (continuing through my previous example):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
.
.
.
A* myProcessedArray;
int size = 10;
int myLimit = 3;

int main()
{
    if( myCondition )
    {
        A* myArray;
        myArray = DoSomethingFunction(myArray);

        myProcessedArray = new A[size];
        for(int i = 0; i < size; i++)
                myProcessedArray[i] = myArray[i];
    }
    .
    .
    .
    if( myCondition )
    {
        for(int i = myLimit; i < size; i++)
                delete [] myProcessedArray[i].myObj;
    }
    .
    .
    .
}

A* DoSomethingFunction(A* anArray)
{
    anArray = new A[size];
    .
    .
    .
    for(int i = 0; i < size; i++)
         anArray[i].myObj = new B[5];
    .
    .
    .
    return anArray;
}


What happens here is when I do not need the arrays of B inside my A objects I want to delete them but there isn't any difference in RAM.

When I load my data the program holds about 600MB of RAM and 99% of it is held by arrays of B objects. When I pause before the deletion of B arrays and after there isn't any difference in RAM...

Does delete [] only works inside the scope the array was created with the new [] command?

I want to delete them but there isn't any difference in RAM.


It will not indicate whether the requested memory is freed.
The operator is not a method meaning it does not belong to any class nor a scope.
It does work whenever applied.
To release yourself from that caution of the leakage just remember it before taking
extra memory while in a loop with new operator that is quite similar to deleting one,
simply rewriting the allocated pointer.



Does this means that the freed memory can only be used by only for memory requests of my program but not other applications?

As soon as released it is freed. Very few chances to get it back as it was on the moment of the freeing.
So when I use new [] to an object pointer and allocating some memory space, that space is freed when I use delete to a pointer that points to the same memory address that new [] was applied. Correct?

My problem is that I'm writing my program for parallel usage (object oriented MPI) and my coordinator process needs to load all the data to distribute it.

Because of this my main process in the cluster runs out of memory and the program exits. I just wanted to save some memory by deleting the data that is distributed to all the other processes and isn't used by the coordinator.
You should'nt apply it like that. Include the same number in square brackets on deleting
as well.
I've no idea of the MPI but I would prefer the union keyword for this kind.
Hmm I cannot use union cause my object class inherits some MPI classes that are vital to my implementation.

When I used the same number (as I used when new[] was called) for each delete [] I got this compilation error:

delete array size expression used (anachronism)

and as I searched a bit this way of deleting is deprecated.
That is to say overloaded the least.
Include the same number in square brackets on deleting as well.
???
Please read up on syntax before trying to give advice, EverBeginner.

deluvian: If you're not detecting a change in memory usage after supposedly freeing most of the memory you had allocated, one of two things may be happening:
1. Your language implementation is refusing to release resources back to the system. This isn't very likely.
2. You're mismanaging memory. This is more likely. Check that each instance of new is matched by an instance of delete, and the same for new[] and delete[] (and of course that you're not mixing them). Try to move memory management to a lower level, rather than keeping it in main() or anything like that. If at all possible, use STL containers instead of raw arrays to store data. If none of this helps and you have access to one, use a memory debugger such as Valgrind to find memory leaks.
I want to understand how dynamic memory allocation works

I had having read it I would suggest you to quit that research the way it implemented
in the code. The debugger may look quite exiting. Why this one? There are many more
including those in an IDE processes giving beutifuel hexadecmal view. Has anybody seen octal one? Binary ones deprecated long ago, though it would be even clearer to observe strings of bits.
???
Yeah, you read syntax of the preprocessor before messing up the leakage with a container.
Yeah, you read syntax of the preprocessor before messing up the leakage with a container.
Can you repeat that in English?
Is anybody talking to you?
Pages: 12