Can't use malloc + undfined reference to __heap_end

Recently, I have tried to set up the AVR toolchain for an Atmega328P. I managed to get pure virtual methods working with the avr-g++ compiler. However, I can't even perform a simple malloc on a basic structure. Because of this, I can't get the new operator working. The linker fails with this error:

[toolchainRoot]/bin/../lib/gcc/avr/7.3.0/../../../../avr/lib\libc.a(malloc.o):(.data+0x0): undefined reference to `__heap_end'

What I have tried: I added my own definition of __heap_end, based on the Atmega328P documentation. It compiles, but my test LED is very faint, as if the MCU were restarting again and again. So it seems no good at all.

I've tested my code on the Arduino IDE, and it works perfectly. I know Arduino put a lot of effort into making all the C++ features work, but I can't manage to find what they added to solve specifically this issue.

I can send my code if needed, but for now, I just try to make a (myStruct*)malloc(sizeof(myStruct)) works

What I need help for:

  • Figure out, what's missing in the toolchain I'm using (incomplete linker? missing definitions? wrong libc.a? Must I use some compile option to tell the linker to do specific things?)
  • Get malloc, and so the new/delete operator working

PS: I'm not used to forum, don't hesitate to tell me if this kind of post are too long or too imprecise

so if the IDE works, why not use it?

...at least as an example?

How, exactly?
Malloc should work fine in a standard avr-gcc toolchain


I use CMake with a cmake toolchain file. I set the C compiler, C++ compiler,avr- ld and avr-objcopy CMakeVariable and run cmake —toolchain path -B build -G Ninja to build my project

But for the simple malloc(myStruct) test I just used avr-gcc main.c -o main.o in a terminal and got the same error

Because I want to use an other IDE that has more features and which I’m more used to. And I just wanted to try to write and HAL in C++ without using Arduino « for fun »

Here is my test code for a malloc. It does nothing with the board register and it's in C, not in C++ because I wanted to try to isolate the issue

in main.c:

#include <stdlib.h>

typedef struct {
    int a;
    char b;
} myStruct;

int main(void) {
    myStruct* test = (myStruct*)malloc(sizeof(myStruct));

    if (test == NULL) {
        return -1;
    }
    test->a = 2;
    test->b = 3;

    free(test);

    while (1) {

    }

    return 0;
}

Command to compile the code:

avr-gcc main.c -o main.o

Error:

toolchainroot/bin/../lib/gcc/avr/7.3.0/../../../../avr/lib\libc.a(malloc.o):(.data+0x0): undefined reference to `__heap_end'
collect2.exe: error: ld returned 1 exit status

This is not enough. With this line you just compiled a separate file. Arduino build includes several stages with a large number of libraries and included files, you don’t have any of this

What's IDE?
Do you know that Arduino IDE is not the only option to build arduino sketches?
There are a many other ways to compile Arduino code with advanced IDE such as Visual Studio, Visual Studio Code, Visual Micro, Platformio, Eclipse and so on

Moreover, the new version of Arduino IDE 2.x.x is also quite an advanced development environment, very different from Arduino IDE 1.x

I'm using CLion.
What should I add to my avr-gcc command? I looked at what ArduinoIDE was doing to perform the compilation and the linking but I can't find what is missing.

If you enable verbose output during compilation under file/prefeences, you can see what is all compiled and linked. You will also see a path to an .ino.cpp file in a temporary directory. You can open that file to see what the ino file looks like that is compiled; it e.g. includes Arduino.h as the first step, it throws function prototypes in (hopefully at the right place else you will have compiler errors).

You can find a working CMake setup here: GitHub - tttapa/Arduino-AVR-CMake: Compile Arduino AVR programs using CMake.

For the flags specifically, see

You can find the ones used by Arduino itself in ArduinoCore-avr/platform.txt at master · arduino/ArduinoCore-avr · GitHub.

1 Like

I'm currently testing the solution you gave me and it seems very promising! I juste have a few issue since I'm using Windows and ninja as a build tool but it should be good

I'll tell you if it worked after a few more hours

It works!!!!! Thanks a lot for your help!!

In particular, it is missing a -mmcu=atmega328p option, which is needed to tell the tools which libraries and linker scripts to use.
You don't need ALL the extra switches that the Arduino IDE adds, for simple programs (but do investigate what they do!)

2441> avr-gcc mtest.c -mmcu=atmega328
/usr/local/avr8-Microchip-3.7.0/bin/../lib/gcc/avr/7.3.0/../../../../avr/lib/libc.a(malloc.o):(.data+0x0): undefined reference to `__heap_end'
collect2: error: ld returned 1 exit status

2442> avr-gcc mtest.c -mmcu=atmega328
2443>  #  (worked!)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.