user136: The use of malloc() and free() seems pretty rare in the Arduino world. It is used in pure AVR C much more often, but still with caution.
Is it a really bad idea to use malloc() and free() with Arduino?

user13432: 
Is it a really bad idea to use malloc() and free() with Arduino?

The short answer is yes. Below are the reasons why:
It is all about understanding what an MPU is and how to program within the constraints of the available resources. The Arduino Uno uses an ATmega328p MPU with 32KB ISP flash memory, 1024B EEPROM, and 2KB SRAM. That is not a lot of memory resources. 
Remember that the 2KB SRAM is used for all global variables, string literals, stack and possible usage of the heap. The stack also needs to have head room for an ISR. 
The memory layout is:

Todays PC/laptops have more than 1.000.000 times the amount of memory. A 1 Mbyte default stack space per thread is not uncommon but totally unrealistic on an MPU. 
An embedded software project has to do a resource budget. This is estimating  ISR latency, necessary memory space, compute power, instruction cycles, etc. There are unfortunately no free-lunches and hard real-time embedded programming is the most difficult of programming skills to master.

user42: Using dynamic allocation (via malloc/free or new/delete) isn't inherently bad as such. In fact, for something like string processing (e.g. via the String object), it's often quite helpful. That's because many sketches use several small fragments of strings, which eventually get combined into a larger one. Using dynamic allocation lets you use only as much memory as you need for each one. In contrast, using a fixed-size static buffer for each one could end up wasting a lot of space (causing it to run out of memory much faster), although it depends entirely on the context.
With all of that being said, it's very important to make sure memory usage is predictable. Allowing the sketch to use arbitrary amounts of memory depending on run-time circumstances (e.g. input) can easily cause a problem sooner or later. In some cases, it might be perfectly safe, e.g. if you know the usage will never add up to much. Sketches can change during the programming process though. An assumption made early-on could be forgotten when something is changed later, resulting in an unforeseen problem.
For robustness, it's usually better to work with fixed-size buffers where possible, and design the sketch to work explicitly with those limits from the outset. That means any future changes to the sketch, or any unexpected run-time circumstances, should hopefully not cause any memory problems.

user10140: I disagree with people who think you shouldn't use it or it is generally unnecessary. I believe it can be dangerous if you don't know the ins and outs of it, but it is useful. I do have cases where I don't know (and shouldn't care to know) the size of a structure or a buffer (at compile time or run time), especially when it comes to libraries I send out into the world. I agree that if you're application is only dealing with a single, known structure, you should just bake in that size at compile time.
Example: I have a serial packet class (a library) that can take arbitrary length data payloads (can be struct, array of uint16_t, etc.). On the sending end of that class you simply tell the Packet.send() method the address of the thing you wish to send and the HardwareSerial port through which you wish to send it. However, on the receiving end I need a dynamically allocated receive buffer to hold that incoming payload, as that payload could be a different structure at any given moment, depending on the application's state, for instance. IF I'm only ever sending a single structure back and forth, I'd just make the buffer the size it needs to be at compile time. But, in the case where packets may be different lengths over time, malloc() and free() are not so bad.
I've run tests with the following code for days, letting it loop continuously, and I've found no evidence of memory fragmentation. After freeing the dynamically allocated memory, the free amount returns to its previous value.
// found at learn.adafruit.com/memories-of-an-arduino/measuring-free-memory
int freeRam () {
    extern int __heap_start, *__brkval;
    int v;
    return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

uint8_t *_tester;

while(1) {
    uint8_t len = random(1, 1000);
    Serial.println("-------------------------------------");
    Serial.println("len is " + String(len, DEC));
    Serial.println("RAM: " + String(freeRam(), DEC));
    Serial.println("_tester = " + String((uint16_t)_tester, DEC));
    Serial.println("alloating _tester memory");
    _tester = (uint8_t *)malloc(len);
    Serial.println("RAM: " + String(freeRam(), DEC));
    Serial.println("_tester = " + String((uint16_t)_tester, DEC));
    Serial.println("Filling _tester");
    for (uint8_t i = 0; i < len; i++) {
        _tester[i] = 255;
    }
    Serial.println("RAM: " + String(freeRam(), DEC));
    Serial.println("freeing _tester memory");
    free(_tester); _tester = NULL;
    Serial.println("RAM: " + String(freeRam(), DEC));
    Serial.println("_tester = " + String((uint16_t)_tester, DEC));
    delay(1000); // quick look
}

I haven't seen any sort of degradation in RAM or in my ability to allocate it dynamically using this method, so I'd say it's a viable tool. FWIW.

user84: Typically, when writing Arduino sketches, you will avoid dynamic allocation (be it with malloc or new for C++ instances), people rather use global -or static- variables, or local (stack) variables.
Using dynamic allocation can lead to several problems:

memory leaks (if you lose a pointer to a memory you previously allocated, or more likely if you forget to free the allocated memory when you don't need it anymore)
heap fragmentation (after several malloc/free calls) where the heap grows bigger thant the actual amount of memory allocated currently

In most situations I have faced, dynamic allocation was either not necessary, or could be avoided with macros as in the following code sample:
MySketch.ino
#define BUFFER_SIZE 32
#include "Dummy.h"

Dummy.h
class Dummy
{
    byte buffer[BUFFER_SIZE];
    ...
};

Without #define BUFFER_SIZE, if we wanted Dummy class to have a non-fixed buffer size, we would have to use dynamic allocation as follows:
class Dummy
{
    const byte* buffer;

    public:
    Dummy(int size):buffer(new byte[size])
    {
    }

    ~Dummy()
    {
        delete [] bufer;
    }
};

In this case, we have more options than in the first sample (e.g. use different Dummy objects with different buffer size for each), but we may have heap fragmentation issues.
Note the use of a destructor to ensure dynamically allocated memory for buffer will be freed when a Dummy instance is deleted.

user7508: I have taken a look at the algorithm used by malloc(), from avr-libc,
and there seems
to be a few usage patterns that are safe from the point of view of heap
fragmentation:
1. Allocate only long-lived buffers
By this I mean: allocate all you need at the beginning of the program,
and never free it. Of course, in this case, you could as well use static
buffers...
2. Allocate only short-lived buffers
Meaning: you free the buffer before allocating anything else. A
reasonable example might look like this:
void foo()
{
    size_t size = figure_out_needs();
    char * buffer = malloc(size);
    if (!buffer) fail();
    do_whatever_with(buffer);
    free(buffer);
}

If there is no malloc inside do_whatever_with(), or if that function
frees whatever it allocates, then you are safe from fragmentation.
3. Always free the last allocated buffer
This is a generalization of the two previous cases. If you use the heap
like a stack (last in is first out), then it will behave like a stack
and not fragment. It should be noted that in this case it is safe to
resize the last allocated buffer with realloc().
4. Always allocate the same size
This will not prevent fragmentation, but it is safe in the sense that
the heap will not grow larger than the maximum used size. If all your
buffers have the same size, you can be sure that, whenever you free one
of them, the slot will be available for subsequent allocations.

user313: My general rule for embedded systems is to only malloc() large buffers and only once, at the start of the program, e.g., in setup(). The trouble comes when you allocate and de-allocate memory. Over a long run session, memory becomes fragmented and eventually an allocation fails due to lack of a sufficiently large free area, even though the total free memory is more than adequate for the request.
(Historical perspective, skip if not interested): Depending on the loader implementation, the only advantage of run-time allocation vs. compile-time allocation (intialized globals) is the size of the hex file. When embedded systems were built with off the shelf computers having all volatile memory, the program was often uploaded to the embedded system from a network or an instrumentation computer and the upload time was sometimes an issue. Leaving out buffers full of zeros from the image could shorten the time considerably.)
If I need dynamic memory allocation in an embedded system, I generally malloc(), or preferably, statically allocate, a large pool and divide it into fixed-size buffers (or one pool each of small and large buffers, respectively) and do my own allocation/de-allocation from that pool. Then every request for any amount of memory up to the fixed buffer size is honored with one of those buffers. The calling function doesn't need to know whether it's larger than requested, and by avoiding splitting and re-combining blocks we solve fragmentation. Of course memory leaks can still occur if the program has allocate/de-allocate bugs.
Update 02/16/23:

I'm curious why the Arduino library's malloc implementation doesn't
implement some coalescing of the free blocks like a full OS would.

That's interesting to think about, but let's first be clear that in C/C++, malloc() and free() are implemented as library functions at the application-level not the OS level, even in major OSes. And they are based on fragmenting the heap, just as the Arduinos' malloc() functions do.
Embedded systems, are relatively new, at least as an influential force in the design of OSes, languages, and libraries' design. Which is to say, programs that had to run "forever" without failing (other than, perhaps the OS itself) were outliers. Most programs we run on our desktops or (once upon a time) ran on mainframes, were started, processed a batch of data, and exited.
Secondly, the malloc()/free() method of memory allocation/deallocation was simple, where anticipating the sizes of memory requests was not; and some allocations are used briefly and returned, where some are kept for the duration of the run. How is a library designer to provide for coalescing currently free and newly deallocated memory with no knowledge of the allocate/deallocate usage and sizes of requests? The fixed-size buffer scheme I described above doesn't suffer the fragmentation problem that "malloc() an arbitrary number of bytes" scheme does. It is still limited to available memory but within that limitation, could meet the "run forever" requirement. There may be algorithms that split and coalesce memory, but probably only for a few - statistically predictable - patterns of allocation and deallocation.
Update 02/18/23:
@edgarbonet points out that Arduino's free() does try to coalesce free blocks. This is a good example of an algorithm that works for certain cases: Properly done, it would work for "last-out / first-in" cases, and to some extent for some other cases.
The trouble is, most of our use patterns are not very regular, if they're regular at all. An alogrithm that does no splitting, but merely allocates & deallocates fixed-size pieces (rather like loaning library books) can still run out of memory but won't end up with fragmented resources. In fact, because it doesn't split, it will need more memory to meet the same random-sized requests than even a coalescing malloc() and free().

136: <p>The use of <code>malloc()</code> and <code>free()</code> seems pretty rare in the Arduino world. It is used in pure AVR C much more often, but still with caution.</p>

<p>Is it a really bad idea to use <code>malloc()</code> and <code>free()</code> with Arduino?</p>
 13432: <blockquote>
  <p>Is it a really bad idea to use malloc() and free() with Arduino?</p>
</blockquote>

<p>The short answer is yes. Below are the reasons why:</p>

<p>It is all about understanding what an MPU is and how to program within the constraints of the available resources. The Arduino Uno uses an <a href="http://www.atmel.com/images/Atmel-8271-8-bit-AVR-Microcontroller-ATmega48A-48PA-88A-88PA-168A-168PA-328-328P_datasheet_Complete.pdf" rel="nofollow noreferrer">ATmega328p</a> MPU with 32KB ISP flash memory, 1024B EEPROM, and 2KB SRAM. That is not a lot of memory resources. </p>

<p>Remember that the 2KB SRAM is used for all global variables, string literals, stack and possible usage of the heap. The stack also needs to have head room for an ISR. </p>

<p>The <a href="http://www.nongnu.org/avr-libc/user-manual/malloc.html" rel="nofollow noreferrer">memory layout</a> is:</p>

<p><a href="https://i.stack.imgur.com/YJsy5.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/YJsy5.png" alt="SRAM map"></a></p>

<p>Todays PC/laptops have more than 1.000.000 times the amount of memory. A 1 Mbyte default stack space per thread is not uncommon but totally unrealistic on an MPU. </p>

<p>An embedded software project has to do a resource budget. This is estimating  ISR latency, necessary memory space, compute power, instruction cycles, etc. There are unfortunately no free-lunches and hard real-time embedded programming is the most <a href="https://en.wikipedia.org/wiki/COCOMO" rel="nofollow noreferrer">difficult</a> of programming skills to master.</p>
 42: <p>Using dynamic allocation (via <code>malloc</code>/<code>free</code> or <code>new</code>/<code>delete</code>) isn't inherently bad as such. In fact, for something like string processing (e.g. via the <code>String</code> object), it's often quite helpful. That's because many sketches use several small fragments of strings, which eventually get combined into a larger one. Using dynamic allocation lets you use only as much memory as you need for each one. In contrast, using a fixed-size static buffer for each one could end up wasting a lot of space (causing it to run out of memory much faster), although it depends entirely on the context.</p>

<p>With all of that being said, it's very important to make sure memory usage is predictable. Allowing the sketch to use arbitrary amounts of memory depending on run-time circumstances (e.g. input) can easily cause a problem sooner or later. In some cases, it might be perfectly safe, e.g. if you <em>know</em> the usage will never add up to much. Sketches can change during the programming process though. An assumption made early-on could be forgotten when something is changed later, resulting in an unforeseen problem.</p>

<p>For robustness, it's usually better to work with fixed-size buffers where possible, and design the sketch to work explicitly with those limits from the outset. That means any future changes to the sketch, or any unexpected run-time circumstances, should hopefully not cause any memory problems.</p>
 10140: <p>I disagree with people who think you shouldn't use it or it is generally unnecessary. I believe it can be dangerous if you don't know the ins and outs of it, but it is useful. I do have cases where I don't know (and shouldn't care to know) the size of a structure or a buffer (at compile time or run time), especially when it comes to libraries I send out into the world. I agree that if you're application is only dealing with a single, known structure, you should just bake in that size at compile time.</p>

<p>Example: I have a serial packet class (a library) that can take arbitrary length data payloads (can be struct, array of uint16_t, etc.). On the sending end of that class you simply tell the Packet.send() method the address of the thing you wish to send and the HardwareSerial port through which you wish to send it. However, on the receiving end I need a dynamically allocated receive buffer to hold that incoming payload, as that payload could be a different structure at any given moment, depending on the application's state, for instance. IF I'm only ever sending a single structure back and forth, I'd just make the buffer the size it needs to be at compile time. But, in the case where packets may be different lengths over time, malloc() and free() are not so bad.</p>

<p>I've run tests with the following code for days, letting it loop continuously, and I've found no evidence of memory fragmentation. After freeing the dynamically allocated memory, the free amount returns to its previous value.</p>

<pre><code>// found at learn.adafruit.com/memories-of-an-arduino/measuring-free-memory
int freeRam () {
    extern int __heap_start, *__brkval;
    int v;
    return (int) &amp;v - (__brkval == 0 ? (int) &amp;__heap_start : (int) __brkval);
}

uint8_t *_tester;

while(1) {
    uint8_t len = random(1, 1000);
    Serial.println("-------------------------------------");
    Serial.println("len is " + String(len, DEC));
    Serial.println("RAM: " + String(freeRam(), DEC));
    Serial.println("_tester = " + String((uint16_t)_tester, DEC));
    Serial.println("alloating _tester memory");
    _tester = (uint8_t *)malloc(len);
    Serial.println("RAM: " + String(freeRam(), DEC));
    Serial.println("_tester = " + String((uint16_t)_tester, DEC));
    Serial.println("Filling _tester");
    for (uint8_t i = 0; i &lt; len; i++) {
        _tester[i] = 255;
    }
    Serial.println("RAM: " + String(freeRam(), DEC));
    Serial.println("freeing _tester memory");
    free(_tester); _tester = NULL;
    Serial.println("RAM: " + String(freeRam(), DEC));
    Serial.println("_tester = " + String((uint16_t)_tester, DEC));
    delay(1000); // quick look
}
</code></pre>

<p>I haven't seen any sort of degradation in RAM or in my ability to allocate it dynamically using this method, so I'd say it's a viable tool. FWIW.</p>
 84: <p>Typically, when writing Arduino sketches, you will avoid dynamic allocation (be it with <code>malloc</code> or <code>new</code> for C++ instances), people rather use global -or <code>static</code>- variables, or local (stack) variables.</p>

<p>Using dynamic allocation can lead to several problems:</p>

<ul>
<li>memory leaks (if you lose a pointer to a memory you previously allocated, or more likely if you forget to free the allocated memory when you don't need it anymore)</li>
<li>heap fragmentation (after several <code>malloc</code>/<code>free</code> calls) where the heap grows bigger thant the actual amount of memory allocated currently</li>
</ul>

<p>In most situations I have faced, dynamic allocation was either not necessary, or could be avoided with macros as in the following code sample:</p>

<p><strong>MySketch.ino</strong></p>

<pre><code>#define BUFFER_SIZE 32
#include "Dummy.h"
</code></pre>

<p><strong>Dummy.h</strong></p>

<pre><code>class Dummy
{
    byte buffer[BUFFER_SIZE];
    ...
};
</code></pre>

<p>Without <code>#define BUFFER_SIZE</code>, if we wanted <code>Dummy</code> class to have a non-fixed <code>buffer</code> size, we would have to use dynamic allocation as follows:</p>

<pre><code>class Dummy
{
    const byte* buffer;

    public:
    Dummy(int size):buffer(new byte[size])
    {
    }

    ~Dummy()
    {
        delete [] bufer;
    }
};
</code></pre>

<p>In this case, we have more options than in the first sample (e.g. use different <code>Dummy</code> objects with different <code>buffer</code> size for each), but we may have heap fragmentation issues.</p>

<p>Note the use of a destructor to ensure dynamically allocated memory for <code>buffer</code> will be freed when a <code>Dummy</code> instance is deleted.</p>
 7508: <p>I have taken a look at the algorithm used by <code>malloc()</code>, from avr-libc,
and there seems
to be a few usage patterns that are safe from the point of view of heap
fragmentation:</p>

<h2>1. Allocate only long-lived buffers</h2>

<p>By this I mean: allocate all you need at the beginning of the program,
and never free it. Of course, in this case, you could as well use static
buffers...</p>

<h2>2. Allocate only short-lived buffers</h2>

<p>Meaning: you free the buffer before allocating anything else. A
reasonable example might look like this:</p>

<pre><code>void foo()
{
    size_t size = figure_out_needs();
    char * buffer = malloc(size);
    if (!buffer) fail();
    do_whatever_with(buffer);
    free(buffer);
}
</code></pre>

<p>If there is no malloc inside <code>do_whatever_with()</code>, or if that function
frees whatever it allocates, then you are safe from fragmentation.</p>

<h2>3. Always free the last allocated buffer</h2>

<p>This is a generalization of the two previous cases. If you use the heap
like a stack (last in is first out), then it will behave like a stack
and not fragment. It should be noted that in this case it is safe to
resize the last allocated buffer with <code>realloc()</code>.</p>

<h2>4. Always allocate the same size</h2>

<p>This will not prevent fragmentation, but it is safe in the sense that
the heap will not grow larger than the maximum <em>used</em> size. If all your
buffers have the same size, you can be sure that, whenever you free one
of them, the slot will be available for subsequent allocations.</p>
 313: <p>My general rule for embedded systems is to only <code>malloc()</code> large buffers and only once, at the start of the program, e.g., in <code>setup()</code>. The trouble comes when you allocate and de-allocate memory. Over a long run session, memory becomes fragmented and eventually an allocation fails due to lack of a sufficiently large free area, even though the total free memory is more than adequate for the request.</p>
<p>(Historical perspective, skip if not interested): Depending on the loader implementation, the only advantage of run-time allocation vs. compile-time allocation (intialized globals) is the size of the hex file. When embedded systems were built with off the shelf computers having all volatile memory, the program was often uploaded to the embedded system from a network or an instrumentation computer and the upload time was sometimes an issue. Leaving out buffers full of zeros from the image could shorten the time considerably.)</p>
<p>If I need dynamic memory allocation in an embedded system, I generally <code>malloc()</code>, or preferably, statically allocate, a large pool and divide it into fixed-size buffers (or one pool each of small and large buffers, respectively) and do my own allocation/de-allocation from that pool. Then every request for any amount of memory up to the fixed buffer size is honored with one of those buffers. The calling function doesn't need to know whether it's larger than requested, and by avoiding splitting and re-combining blocks we solve fragmentation. Of course memory leaks can still occur if the program has allocate/de-allocate bugs.</p>
<p>Update 02/16/23:</p>
<blockquote>
<p>I'm curious why the Arduino library's malloc implementation doesn't
implement some coalescing of the free blocks like a full OS would.</p>
</blockquote>
<p>That's interesting to think about, but let's first be clear that in C/C++, malloc() and free() are implemented as library functions at the application-level not the OS level, even in major OSes. And they are based on fragmenting the heap, just as the Arduinos' malloc() functions do.</p>
<p>Embedded systems, are relatively new, at least as an influential force in the design of OSes, languages, and libraries' design. Which is to say, programs that had to run &quot;forever&quot; without failing (other than, perhaps the OS itself) were outliers. Most programs we run on our desktops or (once upon a time) ran on mainframes, were started, processed a batch of data, and exited.</p>
<p>Secondly, the malloc()/free() method of memory allocation/deallocation was simple, where anticipating the sizes of memory requests was not; and some allocations are used briefly and returned, where some are kept for the duration of the run. How is a library designer to provide for coalescing currently free and newly deallocated memory with no knowledge of the allocate/deallocate usage and sizes of requests? The fixed-size buffer scheme I described above doesn't suffer the fragmentation problem that &quot;malloc() an arbitrary number of bytes&quot; scheme does. It is still limited to available memory but within that limitation, could meet the &quot;run forever&quot; requirement. There may be algorithms that split and coalesce memory, but probably only for a few - statistically predictable - patterns of allocation and deallocation.</p>
<p>Update 02/18/23:</p>
<p>@edgarbonet points out that Arduino's <code>free()</code> does try to coalesce free blocks. This is a good example of an algorithm that works for certain cases: Properly done, it would work for &quot;last-out / first-in&quot; cases, and to some extent for some other cases.</p>
<p>The trouble is, most of our use patterns are not very regular, if they're regular at all. An alogrithm that does no splitting, but merely allocates &amp; deallocates fixed-size pieces (rather like loaning library books) can still run out of memory but won't end up with fragmented resources. In fact, because it doesn't split, it <em>will</em> need more memory to meet the same random-sized requests than even a coalescing <code>malloc()</code> and <code>free()</code>.</p>
