SparkFun Forums 

Where electronics enthusiasts find answers.

Everything ARM and LPC
By xocket
#96236
Hello!
I need to be able to compile C++ code (using dynamic memory allocation with new/delete) on a LPC2378 (and LPC2478) with several different GNU-flavoured toolchains (yagarto, ride, hitex...). I've been trying to solve this on my own, with a little help from google, for about a week now without success. It's working great using C++ without dynamic memory allocation, but I really do need it. Has anybody here done anything similar? Got any tips or pointers? Maybe even an example?

Grateful for any help!
--j.l.
By monstrum
#96238
In my experience, if all is good except dynamic memory allocation, it usually means that the heap has not been set-up correctly.
By xocket
#96333
Thank you for your reply.
The thing is, when using the keyword new in my code, I can't even link. It gives me
Code: Select all
undefined reference to `operator new[](unsigned long)'
even though I'm using arm-elf-g++ to compile and link and I added libstdc++.
By xocket
#96338
Please disregard the previous post, errors were due to erroneous paths...
By JJ
#96723
You don't really need libstdc++ if you don't use RTTI or exceptions. You can disable them by compiling with -fno-rtii -fno-exceptions. You can define your own new/delete to wrap malloc; you'll probably want this anyway since if you compile without exceptions new will return NULL on allocation failures, while you'd probably prefer to stop in an assert waiting for a debugger (via JTAG) or flash a LED, or possibly reset, depending on what you're building for (dev or deployment). There are very few ABI functions, and none of them likely do anything you'll need so you can easily stub them out. Compile and link using ld (as opposed to the frontend) and see what you get undefined. Google the functions to see what they do. It'll be things like atexit() registrations and termination code. Given that embedded code rarely has any need to cleanup at exit since it's not intended to ever exit, you can just stub things like this it out to satisfy the linker. Once you get that working, go over the default ld script and remove what you don't need, like global/static destructors, and provide your own startup that runs global constructors and sets up a top-level C frame. (Some of the common ones on the net don't do this.)

Just to give a sense of what's needed, here's what I stubbed for a recent project:
Code: Select all

#undef abort
void abort() { panic("ABORT"); }


// ABI stuff

extern "C" {
int __cxa_atexit(void (*func) (void*), void* arg, void* dso_handle);
int __cxa_pure_virtual();
}

int __cxa_atexit(void (*func) (void*), void* arg, void* dso_handle)
{
	return 0;
}

int __cxa_pure_virtual() { abort(); return 0; }

void*   __dso_handle = (void*) &__dso_handle;
By xocket
#96828
Thank you JJ for the information!

This problem has been solved, C++ code with dynamic memory allocation and exception handling is running smoothly. The crucial thing was that the link script which has been in use for C code only projects lacked parts describing the location of memory to be used for constructors/destructors.

So, thanks again for your help!

--j.l.
By littledino2112
#144401
I'm having an issue with this matter as well. I'd be great if u can the solution in more detail.
Thanks a lot.
By stevech
#144501
xocket wrote:Thank you JJ for the information!

This problem has been solved, C++ code with dynamic memory allocation and exception handling is running smoothly. The crucial thing was that the link script which has been in use for C code only projects lacked parts describing the location of memory to be used for constructors/destructors.

So, thanks again for your help!

--j.l.
indeed, if there's delete and free() and some randomness, as time goes by, the heap gets fragmented and the garbage collector (if there is one), on a small micro, struggles. If you don't do delete/free much, you can sneak by. Or preclude irregular-sized objects from delete/free.