How to use C++ memory management routines in Objective C module? - c++

I need to use C++ memory allocation routines in my Objective C iOS project. However, compiler does not recognize new/delete operators yielding Use of undeclared identifier "new".
char *armsciiBuffer = new char[numberOfUnicodeChars];
...
delete [] armsciiBuffer;
What is the workaround here? I could use malloc, but new/delete would have been much better.

Compile the code as Objective-C++. Either add the -x obj-c++ compiler flag, or name your source file Foo.mm.

Related

Alternatives to IMalloc_Free and IMalloc_release

For freeing memory used by the SHGetFolderLocation() API, I use IMallloc_Free() and IMalloc_Release().
This compiles fine when including
#define COBJMACROS
#define CINTERFACE
However, in some files, specifically ATL header included files, this results in compiler issues. However, there pMalloc->Free() and pMalloc-Release() work.
Is there any free and release method which works for both of these files?
Generally no, you either use C way to work with COM, or C++ way.
Specifically for IMalloc here, however, just use CoTaskMemFree instead. Default IMalloc and CoTaskMemFree are compatible, and COM does its allocations compatible with them.
SHGetFolderLocation is documented to be deallocated with ILFree, but see remark in ILFree documentation.
See also How to use IMalloc::Free?. The linked post explains that in older systems shell allocation could be incompatible with COM allocation, so you could not use IMalloc::Free or CoTaskMemFree for ILFree, but now you can (assuming you don't support historic OSes).

using free(const char *) in c++ 11

In one of my c++ functions I am calling ab demangle. I want to deallocate result after changing that to string. Here is the code:
const char * realName;
string name;
const std::type_info &ti = typeid(*this);
realName = abi::__cxa_demangle(ti.name(), 0, 0, &status);
name= realName;
int index =name.find_last_of(':');
name = name.substr(index+1, name.length()-index-1);
free((void *) realName);
The code is running without problem but eclipse compiler is not happy and showing an error for using free: "Function 'free' could not be resolved".
I tried to use delete instead of free.
delete realName;
The code is running without problem and eclipse compiler is happy, however when I am profiling code with valgrind, I am getting a profiling error:
Mismatched free() / delete / delete []
So my question is:
1- Should I use free in c++ or shall I use just delete, delete []
2- If I should not use free why valgrind giving me an error
3- If I should use free why eclipse cdt comipler is giving me a compile error but when I am running code everything is ok.
4- is my code has correct style based on c++11? or is it a combination of c and old c++?
Should I use free in C++ or shall I use just delete, delete[]?
You should use the function or the operator that matches the allocation. When you allocate memory for your own use, you should use new/new[] for allocation, and delete/delete[] for deallocation.
When the memory to be deallocated comes from other sources, such as __cxa_demangle, you should read the documentation to see what functionality needs to be used on deallocation. The documentation for your function states that
the demangled name is placed in a region of memory allocated with malloc.
Therefore, you must use free to free it.
If I should use free why Eclipse cdt compiler is giving me a compile error but when I am running code everything is OK.
Function free is defined in <cstdlib> header. You need to add this header to your cpp file to make sure you code compiles fine.
You have to use free as the documentation says use free.
Perhaps you need to include the correct header file and library.
#include <stdlib.h> and maybe -lC

STM32 C++ operator new (CoIDE)

I'm new in ARM programming, I'm using CoIDE, I'm trying to write some application to read PWM from 8 channels, in C++.
My problem is using operator new; if I write:
RxPort rxPort = RxPort(RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_6, GPIO_PinSource6, GPIO_AF_TIM3, RCC_APB1Periph_TIM3, TIM3, TIM_Channel_1, TIM_IT_CC1, TIM3_IRQn);
it works fine, but if I write:
RxPort* rxPort1 = new RxPort;
rxPort1->setTimerParameters(RCC_APB1Periph_TIM3, TIM3, TIM_Channel_1, TIM_IT_CC1, TIM3_IRQn);
rxPort1->setGPIOParameters(RCC_AHB1Periph_GPIOA, GPIOA, GPIO_Pin_6, GPIO_PinSource6, GPIO_AF_TIM3);
rxPort1->init();
program goes to:
static void Default_Handler(void)
{
/* Go into an infinite loop. */
while (1)
{
}
}
after first line.
I've found one topic on my.st.com here, and tried to add "--specs=nano.specs" to "Misc Controls" in "Link" and "Compile" section, but nothing changes.
To support new/delete and malloc/free in GCC with then newlib C library, you must implement the _sbrk_r() syscalls stub, and allocate an area of memory for the heap. Typically the latter is done via the linker script, but you can also simply allocate a large static array. A smart linker script however can be written so that the heap automatically uses all available memory after static object and system stack allocation.
An example sbrk_r() implementation (as well as the other syscall stubs for supporting library features such as stream I/O) can be found on Bill Gatliff's site. If you are using CoOS or any other multitasking OS or executive, and are intending to allocate from multiple threads you will also need to implement __malloc_lock() and __malloc_unlock() too.
Your code ended up in Default_Handler because new is required to throw an exception when it fails and you had no explicit try/catch block. If you would rather have malloc() style semantics and simply return null on failure, you can use the new (std::nothrow).
Apparently your active GCC toolchain newlib stubs don't support use of low level dynamic memory allocation (malloc(),free(), etc.). The usage of new() or delete() for C++ bindings might raise a default 'exception' handler at run time.
The details depend on the newlib stubs provided with your configuration. Note that you can override the stub functions with your own implementations.
You'll find some useful additional hints in this article: Building GCC 4.7.1 ARM cross toolchain on Suse 12.2

NSDictionary - Objective-C code in C++

Is it possible to use NSDictionary inside C++ class ? I know, I can use Objective-C classes inside C++ (http://philjordan.eu/article/mixing-objective-c-c++-and-objective-c++), but for NSDictionary, I need header... but if I do #import, it failed to compile.
PS: I know, I shouldnt mix Objective-C(++) and C++, but I am writing multiplatform OpenGL app and for EAGL initialization one of input parametrs is NSDictionary. I could init OpenGL in Objective-C, but it would break my OOP design.
Sure compile the C++ class as Objective-C++ (.mm extension) and you will have no problems. The only problem I've had doing this is the fact that you can't define the Objective-C++ type inside the C++ header. So instead I use a void* and cast it to void* using a
pVoidDict = (__bridge_retained void*)[NSDictionary dictionary];
You will need to perform a bridged cast to use it:
unsigned int dictCount = [(__bridge NSDictionary*)pVoidDict count];
The only problem is you must remember to release it at the end. You can do this by casting it back to an NSDictionary as follows:
NSDictionary* dict = (__bridge_transfer NSDictionary*)pVoidDict;
This will return it to ARC control and when the destructor exits it will be added to the autorelease pool as per standard ARC rules.
Its not particularly nice to look at but I use this quite a bit in a cross-platform library so that I can wrap Objective-C objects with C++ classes.

operator new already defined in custom memory manager with library

Sorry for the poor title, but hopefully the description makes it clearer.
At the momemnt I have one main application which is built together with other libraries (like libpng, libvorbis,etc.). I'm trying to add libtheoraplayer to the main application, but I keep running into problems:
1) Linking to a pre-built library of llibtheoraplayer and including the appropriate header files gives me an error saying that pushMemoryManager cannot be found (part of our custom memory manager)
2) Building the library together with the main application results in a linker error "error LNK2005: "void * __cdecl operator new(unsigned int,void *)" (??2#YAPAXIPAX#Z) already defined in win32Mem.obj"
I'm not quite sure where to start debugging this. The main application does not support STL, and I started by changing references to STL in the libtheoraplayer to our own STL replacements, but I'm still getting error 2 as above after finding the offending files and changing them.
Any wild ideas?
Silence the linker error (convert to warning) with /FORCE and pray that there are no cross-library allocations ending up using different allocators.
It's rather difficult to replace allocation functions on Windows (NT or CE), because:
Dynamic symbols are loaded from specific libraries, so you will replace which allocator is used in your code, but not which is used in libraries you link dynamically. If you don't link dynamically and silence the linker error with /FORCE, it will do the right thing and override the allocators from standard library just fine.
With dynamic linking if code living in one library allocates and code living in another library frees, there will be mismatch in allocators used and thus probably crash. Unfortunately it may easily happen even if both functions are defined by the same library, but one of them is a template (so the instance lives in the library refering to it) and the other is not (so it lives in the library defining it).
They have some non-standard entry points to the allocator and sometimes use them from other code. We used to use duma library and actually managed to override both C (malloc/realloc/free) and C++ (operator new and operator delete) allocators, but hit a wall when we started using iostreams, where they allocate with the standard function, but free with something like __debug_free or the other way 'round.
On a side-note, the same is absolutely trivial on Linux, because in GNU libc malloc, realloc and free call the real allocator through pointers that you can easily override (operator new and operator delete just call malloc and free respectively basically everywhere).