Arduino Uno - ATMega328P

Arduino String Class alternative (against memory-fragmentation)

Whilst getting more familiar with Arduino and all the pros and cons of the default Arduino eco-system, you might notice the comments everywhere suggesting you shouldn’t Arduino’s built-in String class. And rightfully so! But why? And what should you use instead? That’s what this blog will hopefully provide a satisfying answer to.

TLDR; You can download my library at the bottom of this page.

Arduino’s String can (and probably will) corrupt your memory

Arduino’s built-in String object/library is perfect for simple string operations, like concatenating strings, splitting them or appending to them. However, at some point they will start to fragment the memory of your Arduino, you can read here how that works in detail. But long story short: after a while of fragmenting the memory, your Arduino runs out of usable space, even if you seemingly have enough left.

The problem with situations like these is that they can be very, VERY hard to debug, since Arduino’s will just crash or start acting weird without a clear cause.

But what can I do about it?

Well, there are two main options. The first is storing your strings in fixed-length character arrays. This is nice because you are no longer fragmenting your Arduino’s memory. However, since a character array is nothing more than just that, you can’t just do those pretty operations on them anymore. You could cast the array to a String, do the modifications and then save it again, that is possible, although very inefficient.

void setup() {
  Serial.begin(9600);

  char myString[8] = {'A', 'r', 'd', 'u', 'i', 'n', 'o', '\0'};
  char myNewString[32];

  String temporaryString = String(myString); // Create String from char[]
  temporaryString.concat(" is awesome."); // Add some text
  temporaryString.toCharArray(myNewString, 32); // Store all text in myNewString

  Serial.println(myNewString); // "Arduino is awesome."
}

So in all my frustration, looking for something that would solve my problem I decided to take it up on my own, thus providing you the second (and better) option. My requirements for this were:

  • I should not fragment my memory
  • It must convert from and to character arrays
  • It must be able to do lots of string operations, just like the Arduino’s string (or std::string for that matter)

Out of this, the StackString library was born. This library enables me to easily build Strings and modify them, without the danger of introducing memory fragmentation. The biggest difference with regular Strings is that you have to define a maximum length of the string before compilation. But within that range you can do anything you want without fear.

How to use

Creating a new StackString is dead simple. First include the library on top of your code and make sure you use the namespace it is in:

#include <StackString.hpp>
using namespace Stack; // Important!

Then, in your own code you can add this:

StackString<100> myString = StackString<100>("Hello, World!");

You can, just like regular strings declare it anywhere you want, the only difference is the number between the <>. That’s where you declare the maximum length of the string. In case of the example above that’s 100. Notice that the length of your string’s content doesn’t have to match that number, it just shouldn’t exceed it.

After initializing the StackString, you can perform various operations on it, such as appending, prepending, comparing, searching and printing. A full list of all features can be found here.

Here’s an example of adding text in front of the string declared above:

myString.prepend("Everybody say: ");

When we’re done modifying the string and want to print it. We need to use the c_str() function, this function converts the StackString to a char[] which is an accepted input by almost any other library. Here’s an example of printing out the myString variable:

Serial.println(myString.c_str()); // Prints "Everybody say: Hello, World!"

Where can I get the library?

You can add this library to your project in the following three different ways:

  • Install it through the PlatformIO library manager, which I highly suggest using over the Arduino IDE.
  • Use the Arduino library manager to add the library, just search for StackString and you’ll find it. Don’t know how? Take a look at this tutorial.
  • Lastly, you can download the library as a Zip-file using this link. (Note that you won’t get automatic updates this way)

Useful links

Article on heap fragmentation on cpp4arduino.com
A library for timing of your code: StensTimer
All functionality in the StackString library: StackString

5 thoughts to “Arduino String Class alternative (against memory-fragmentation)”

  1. Nice Library Arjen, thanks for sharing. I try to avoid the use of String on my ESP8266/ESP32 projects and use std::string container. I was wondering if you had looked into that and did a comparison, like solving the heap fragmentation nuances?

    1. Thank you! I haven’t done an in-depth comparison between my library and std::string if that’s what you mean. Might be an interesting future post though, but getting a good test-setup may prove difficult as debugging memory issues can be very complicated on embedded systems.

  2. Hello Arjen,

    happy eastern to you.

    I tried to use your StackString-library.
    As long as I just add the codeline to include the library

    #include

    the code compiles.

    If I add the codeline of your example
    StackString myString = StackString(“Hello, World!”);

    the compiler complains
    ‘StackString’ does not name a type; did you mean ‘StackString_h’?

    So it seems the use is only dead simple for experts. Would you mind adding a short demo-code that is well-tested to compile?

    best regards

    Stefan

    1. Hi Stefan,

      You are right that the demo code is not correct.
      I made a mistake and forgot to add a very important statement in the code.
      If you add using namespace Stack; right after the include statement, the code should compile.
      I will update the examples with this, my apologies for the confusion.

      Kind regards,
      Arjen

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.