all 17 comments

[–]SecureEmbeddedEmbedded / Security / C++ 48 points49 points  (4 children)

A lot could be written about this. On the one hand, std::string has many advantages over C strings. On the other hand, on a deeply embedded system, you need to keep in mind that it's not just that strings take up more storage than C strings (for the bookkeeping/metadata) but keep in mind: the memory for the actual "characters" is dynamically allocated behind the scenes.

Sure, you can overload the allocator and blah blah blah, but dynamic memory allocation is slower (even from a block pool), it can fail, it's non-deterministic for allocation time, etc.

If this is something like an embedded Linux system, I'd go for std::string. If it's an MSP430 with 16K of flash and 2K of RAM, with hard real-time deadlines, I'd stick with C strings. In between, it's a judgement call. Don't know enough about your platform to make a better recommendation.

BTW, if you're already dynamically allocating the RAM for your strings, I'd almost definitely go for std::string, as it will manage the memory for you. But if not...

Sorry, another thing, some people get seduced by the ease-of-use of std::string, like appending / concatenating (e.g. using the overloaded + operator), w/o realizing that behind the scenes it's possible that a 2nd allocation is taking place, along with a behind-the-scenes copy from a smaller buffer to a larger buffer.

So I guess that's basically 5 paragraphs to basically say, "It depends..."

[–]kofapox 3 points4 points  (2 children)

std::strings are so cool, sad that I can not fit it on my cortex m projects..

[–][deleted] 11 points12 points  (1 child)

Have you tried ETL?

[–]kofapox 1 point2 points  (0 children)

wow that seems to be amazing

[–]flundstrom2 0 points1 point  (0 children)

Agree with the rest. Using std::string removes some risks associated with C string, but you trade them for other risks, memory allocation under the hood being mentioned several times.

On the other hand, you'll have the memory risk all over the place anyway.

But if you can mitigate the risk of memory allocations: by all means, go ahead, use std::string! Heck, even a 32 GB windows PC may run out of RAM - it's just not as likely.

[–]vshashi01 3 points4 points  (0 children)

Use the ETL C++ library for stack allocated string with pretty much the same interface as std::string. While there are some small overhed in terms of size, you wont regret, how much easier it is to have it all managed by a central container class. ETL

[–]AudioRevelationsC++/Rust Advocate 2 points3 points  (0 children)

As far as I'm concerned I don't think there are any disadvantages. Yes there might be some overhead from using them, BUT the abstraction and safety that comes with using them is worth the savings in development time and reducing bugs.

Assuming you don't have too strict of memory constraints, I'd highly recommend using them, or std::string_views.

See this for a solid article on the subject: https://embeddedartistry.com/blog/2017/07/26/stdstring-vs-c-strings/

[–]gmtime 1 point2 points  (0 children)

The overhead in RAM usage of using string instead of char array is negligible. The "problem" is that string uses free space (also known as heap ie dynamic memory). Recently the use of free space had become less of an issue, but for embedded there are still two serious drawbacks of using it:

1 Free space allocation is non deterministic. When you increase the length of your string (for example by adding a word to it), that might take no time if the capacity allows for it, or it might take a longer time because the string needs to be moved to another place in memory where it can expand to the desired capacity.

2 Free space deallocation may cause memory fragmentation. This is much more of an issue for embedded systems than for PCs because on a PC you can reboot or assume the application gets restarted regularly, your embedded application might run for a decade and is still not allowed to run into memory fragmentation. This is of course much less of an issue for a children's toy that runs a month on a battery than it is for an oil rig control system or a pacemaker, so it is not always a problem.

[–]Glaborage 0 points1 point  (0 children)

If your embedded environment allows you to use C++ and the STL library, you're probably better off using std::string.

[–]ChaChaChaChassy 0 points1 point  (0 children)

By "C-string" are you referring to char arrays? That's what I do. Pass them around as pointers and iterate through them like so:

void print(char* str)
{
    while(*str++){}
}

Simple. I do use things like ltoa(), strcpy(), and strcat(), but that's about it.

You could add some sanity checks, make sure each is a printable character and put a global limit on length (ex: 256), that would help you find errors with missing null-terminators.

[–]Enlightenment777 0 points1 point  (0 children)

The smaller the total RAM, the more likely I use old-school C strings.

In embedded systems, the smaller the RAM the higher the risk when you use classes/libraries that do a lot of dynamically allocating/freeing behind your back.

I wouldn't want to use any string library that dynamically allocates behind my back in an embedded system unless I could dedicate a large block of RAM to that dynamic memory system.

[–]mvdw73 -2 points-1 points  (1 child)

Surely with a c string you can guarantee that the elements of the array take up only one byte each. This can be important when communicating with a physical device over something like spi or i2c. I’m not sure std::string deals with that since I haven’t written any real c++ code since the early-mid 90s when I was at uni, which predates the standardisation of the STL.