The IOPoint interface returns a pointer (allocated by the RSI library).
Is it a good idea for me to delete this memory when I’m finished with it? The 7.3.2 changelog says that it will be cleaned up when the Motion Controller exits. I don’t want these objects to accumulate during the course of a run (days to weeks long), but I’m also a little leery of freeing memory allocated by a different C runtime (It looks like you use VS 2010, whereas I’m using VS 2017).
Have you done something to ensure that the object returned can be free’d (
delete actually) without risking problems due to binary incompatibilities between some C++ runtimes? It is (or should be) common to ensure that the same runtime performs both the allocation and deallocation.
I don’t have any examples of crashes that I’ve encountered with this. It just makes me anxious to (directly) deallocate memory allocated by someone else.
For example, in The Perils of C++-Interface DLLs, the author states:
In the presence of dynamically-allocated objects exchanged between the DLL and the EXE, the exported component and all the modules using it must use the same memory allocator . In other words, the code that allocates memory and the code that frees it must use the same allocator.
Here’s another one, Mixing Multiple Visual Studio Versions in a Program is Evil
In general passing CRT objects across CRT instance boundary (within which they are created and managed) is a bad practice and should be avoided.
Dynamic memory is allocated when you do
new (C++) or
malloc (C/C++). Dynamic memory is allocated on heap. Each CRT instance manages its own heap. Whereas local variables, function parameters, and return values are created on the stack. The program, not the CRT instance, manages the stack.
The pointers returned by the RMP are managed by the library and should not be freed (IOPoints included)
We do this 1) so that users don’t need to worry about managing memory and 2) to avoid the problems that freeing objects created from a different CRT version can cause.
We’re expecting users to keep the pointers to RapidCode objects and make use of them throughout the lifespan of your project (or at least the lifespan of your MotionController instance). They weren’t intended for Creation and Deletion in a method call leveraging their functionality.
In my case, there are times when, because the API requires it, I want to “resolve” an I/O and get its host address. The IOPoint interface is useful to that end, but I don’t really need the IOPoint object(s) beyond the address lookup.
Is there a better way to accomplish what I need?
If I do not attempt to deallocate the
IOPoint* object, is my process going to leak this memory, or does RMP never create more than one real IOPoint object for a given I/O?
Not that this will surprise you, but I wrote a quick app to instantiate an IOPoint* (for the same underlying I/O) in a loop. It definitely allocated more memory each time.
Unless something is added to the API to allow destroying (or re-using e.g. AxisGet(), Is this correct?) the IOPoint, I’ll have to go back to resolving I/O points the old way.