Possibility of memory leak in using environment objects? - swiftui

I have a concern about misusing environment objects and cause potential point memory leak.
Imagine a scenario in which a View creates an object which is passed to an environment object, what would happen to the referenced object when the view is destroyed?

Related

How to know static/global objects which are in memory

We have static and global objects allocated on stack. These objects would be destroyed during process's main (…) function exit.
But I would like to manage destruction of these before main's exit. To destroy these I will have to move the creation logic of these objects to heap and deallocate them.
Is there any tool which tells us what all the static and global objects are still in the memory so that I can go ahead and make the code changes to destroy them.
Use case:
There is a desktop application which uses static and global extensively. I would like to do little bit changes to this and use this as a library which should be stateless. For this during terminateLibrary all these static and global should be destroyed so that we can do subsequent InitLibrary afresh without actually restarting the process.
moving existing architecture to totally a new design is very difficult and time taking, as there are huge number of these objects scattered through out the code. that's why I wanted to find out those static and global which is there in memory even after terminateLibrary called.

Can I use QCoreApplication::instance() for Orphan QObjects?

For QObjects created on the heap with no parent, I found that destructor is not called. So, I starting using the core application instance as their parent to ensure that they are cleaned by garbage collector. Is this the right action, or what should I exactly to safely de-allocated these objects?
Here is an example of what I am doing:
// Use application instance as parent to avoid memory leak if object is not deleted
m_qObject = new DataHandler(QCoreApplication::instance());
Qt doesn't have an independent memory management, such as a garbage collector. The explicit parent-child relationship used is a classic ownership model that helps in the automatization of object life-cycles, it is deterministic (it will delete object on parent's destruction), and it is very natural with user interfaces.
If an object is created (in the heap) without a parent, it will generate a memory leak when the last reference to it is lost. Objects in the stack should not have a parent to prevent double-delete errors (check Qt documentation for further information)
If you set QApplication::instance as the parent of an object, you are basically telling it not to be destroyed until the application quits. If that's the case, then there is no such a great difference with other standard memory leaks, escept the object's destructor does something else than just releasing memory (such as closing OS-wide handles, saving files, etc).
There is a very interesting case I was curious about: what happened when the original parent (Q*Application::instance) was replaced at any given moment, as in this question?
The case is that the ownership of the object is transferred from the former Q*Application instance to the new one. It may become a problem if you rely on the existence of the object through the whole application life-span but several instances of Q*Application are allowed to be created and destroyed at any moment. One scenario would be a non-Qt application loading plug-ins or components built on Qt, in where you cannot control the creation/destruction order.
If that's the case, I'd suggest to find another way to destruct your object, such as having your own singleton inheriting from QObject that you can use as parent.

Memory alocated for Creating object inside a function?

As objects are created from same class. Each object contains the variable defined in the class except those which are defined in the methods of that class. Variable in functions of the same object are shared memory right? If we have a function where we create an object of the same class, where will be the reference reside? Isnt that reference be shared too?
Methods are no different from any other function with regard to memory use: local variables are created when execution reaches their declaration, and (unless static) they are destroyed, and their memory reclaimed, when execution leaves the block it. (This happens, at latest, when the function returns.) There is no connection to the this object or any of its members. Nor does the variable having the same type as the method’s class make any difference.
In some sense, that does make the memory “shared”: it will be rapidly reclaimed and (typically) reused. But that’s nothing special, and don’t think that it means more than it does: if a method is recursive, or invoked concurrently by more than one thread, each copy has its own locals—again, just like any other function.
Finally, any function or method can allocate memory dynamically; the lifetime and sharing of the allocated object may be unrelated to that of the variable used to refer to it.

Can I encounter memory leaks when using vectors of classes? (C++)

I'm using numerous vectors in a program and I want to avoid memory leaks. Here is an example of a vector containing classes I have created myself.
vector<MyClass> objects;
objects = vector<MyClass>(10);
As you can see, I haven't used the "new" operator and the vector is not of a pointer type. Will I still encounter memory leaks without deleting the vector in some way? If so, how can I delete the vector and deallocate the memory?
No, you won't encounter directly a memory leaks related to the vector this way. Indeed, objects is a variable with automatic storage duration. What this means is that the variable you created will live in the scope you created it. If you've created it in a function, and if/for/while/etc scope or even a raw block scope, it will be cleaned up at the end of this same scope, without the need for any actions from your part.
Then, nothing is preventing your class itself from leaking, e.g. if you have ownership of some memory and don't release it as an instance of your class go away.
A memory leak is defined as memory that exists, but you don't have access to anymore because you lost the pointer. Do this in a loop and you will be out of available memory real quick.
If you don't use new to allocate memory dynamically, you cannot have a memory leak.
Lets assume you add instances to this vector in a loop. This consumes a lot of memory. But it's not a leak, because you know exactly where your memory went. And you can still release it if no longer needed.

What's the difference between these two object instantiation approaches?

Suppose I have a class named A:
Class A
{
...
}
And what's the difference between the following 2 approaches to instanciate an object:
void main(void)
{
A a; // 1
A *pa=new A(); // 2
}
As my current understanding (not sure about this yet):
Approach 1 allocate the object a on the stack frame of the main() method, and so this object cannot deleted because that deletion doesn't make sense (don't know why yet, could someone explain that?).
Approach 2 allocate the object a on the heap of the process and also a A* vairable pa on the stack frame of the main() method, so the object can be deleted and and the pa can be assigned null after the deletion.
Am I right? If my understanding is correct, could someone tell me why i cannot delete the a object from the stack in approach 1?
Many thanks...
Object a has automatic storage duration so it will be deleted automatically at the end of the scope in which it is defined. It doesn't make sense to attempt to delete it manually. Manually deletion is only required for objects with dynamic storage duration such as *pa which has been allocated using new.
The objects live time is limited to
the scope the variable is defined
in, once you leave the scope the
object will be cleaned up. In c++ a
scope is defined by any Block
between { an the corresponding }.
Here only the pointer is on the stack and not the object, so when
you leave the scope only the pointer
will be cleaned up, the object will
still be around somewhere.
To the part of deleting an object, delete not only calls the destructor of your object but also releases its memory, this would not work as the memory management of the stack is automated by the compiler, in contrast the heap is not automated and requires calls to new and delete to manage the live time of an object.
Any object created by a call to new has to be deleted once, forgetting to do this results in an memory leak as the objects memory will never be released.
Approach 1 declared a variable and created an object. In Approach 2, you created an instance and pointer to it.
EDIT : In approach 1, the object will go out of scope and will be automatically deleted. In approach 2, the pointer will be automatically deleted, but not what it is pointing to. That will be your job.
Imagine stack as void* stack = malloc(1.000.000);
Now, this memory block is managed internally by the compiler and the CPU.
It is a shared piece of memory. Every function can use it to store temporary objects there.
That's called automatic storage. You cannot delete parts of that memory because its purpose is
to be used again again. If you explicitly delete memory, that memory returns back to the system,
and you don't want that to happen in a shared memory.
In a way, automatic objects are also get deleted. When an object gets out of scope the compiler places
an invisible call to object's destructor and the memory is available again.
You cannot delete objects on the stack because it's implemented in memory exactly that way -- as a stack. As you create objects on the stack, they are added on top of each other. As the objects leave scope, they are destroyed from the top, in the opposite order they were created in (add to the top of the stack, and remove from the top of the stack). Trying to call delete on something in the stack would break that order. The analogy would be like trying to pull some paper out of the middle of a stack of papers.
The compiler controls how objects are created and removed on the stack. It can do this because it knows exactly how large each object on the stack is. Since the stack size is set at compile time, it means that allocating memory for things on the stack is extremely fast, much faster than allocating memory from the heap, which is controlled by the operating system.
Allocation does two things:
1) Allocates memory for the object
2) Calls the constructor on the allocated memory
Deletion does two things:
1) Calls the destructor on the object
2) Deallocates the memory used by the destructed object
When you allocate on the stack (A a;), you're telling the compiler "please make an object for me, by allocating memory, then call the constructor on that memory. And while you're at it, could you handle calling the destructor and freeing the memory, when it goes out of scope? Thanks!". Once the function (main) ends, the object goes out of scope, the destructor is called, and the memory is freed.
When you allocate on the heap (A* pa = new A();), you're telling the compiler "please make an object for me. I know what I'm doing, so don't bother calling the destructor or freeing the memory. I'll tell you when to do it, some other time". Once the function (main) ends, the object you allocated stays in scope, and is not destructed or freed. Hopefully you have a pointer to it stored somewhere else in your program (as in, you copied pa to some other variable with a bigger scope). You're gonna have to tell the compiler to destruct the object and free the memory at some point in the future. Otherwise, you get a memory leak.
Simply put, the "delete" command is only for objects allocated on the heap, because that's the manual memory management interface in C++ - new/delete. It is a command for the heap allocator, and the heap allocator doesn't know anything about stack allocated objects. If you try to call delete on a stack allocated object, you might as well have called it on a random memory address - they're the same thing as far as the heap allocator is concerned. Very much like trying to access an object outside array bounds:
int a[10];
std::cout << a[37] << "\n"; // a[37] points at... ? no one knows!
It just isn't meant to do that :)
Edit:
P.S. Memory leaks are more important when you are allocating memory in a function other than main. When the program ends, leaked memory gets deallocated, so a memory leak in main might not be a big deal, depending on your scenario. However, destructors never get called on leaked objects. If the destructor does something important, like closing a database or a file, then you might have a more serious bug on your hands.
stack memory is not being managed on the same way as heap memory.
there is no point to delete objects from stack: they will be deleted
automatically upon end of scope/function.