String is a piece of TRASH!! Guidelines to replace it at existing code?

I was not aware about how dangerous is the usage of String at an Arduino project. Also, I do not know why the Arduino's developers allow the usage of such a piece of trash that String is. As my project evolved, a strange behavior starts to happen and now I discovered why (see http://arduino.cc/forum/index.php/topic,55502.0.html).

I am not a professional developer, but I just want to use the most "rapid" way to achieve my goals without sacrificing functionality. I do not care about how good a program is in terms of performance and usage of memory if it WORKS and never breaks!! For instance, if my program A was developed in 2 days and uses 50% more memory that other program B, which was developed in 3 days, my preference is A. However, this is only true if the code never crashes for what it is being applied.

Therefore, I would like to ask about a small piece of code that WORKS and (hopefully) is not very complicated to replace all the current String references at my code. I believe there are many ways to do it, especially with the use of array of chars. However, I would like to have the methods summarized here to help me and others to eliminate the use of String at Arduino platform until someone solves the problem.

Thanks!!

Therefore, I would like to ask about a small piece of code that WORKS and (hopefully) is not very complicated to replace all the current String references at my code.

Ask away, but until we can actually see your code, we can't really sensibly answer.

What String functions are you using, and why are you so negative about the String class?

If you are so certain that the String class implementation is flawed, you are free to develop your own String class and remove all the perceived flaws. I'm not saying that there aren't any (because there are), or that the String class couldn't be improved (because it easily could). But, dumping all over the class with out siting specific examples or offering constructive improvements is simply whining.

Please, see the example at http://arduino.cc/forum/index.php/topic,55502.0.html. The issue is not the command and how the String class is being used. Instead, it is related to the free RAM conditions of your MCU. I believe that this object (String) is so RAM-hungry that causes heap overflow without any warning to the developer.

In my case, I was using the developed code and everything was running nice. I just included the String line (see code below) and.... The MCU now is rebooting when it reaches that point of the code... What can I say about String? Yes, it is a TRASH because there is NOTHING stating about this issue at the documentation of the related library. I prefer not to have a class than having something with so dangerous behavior (crashing at run-time!!!).

Yes, I can try to develop by myself such functional String class (who knows?) but, at this moment, I just would like to ask the community to give me simple examples to realize the total "String-wiping" from my existing code. For instance:

String logText = "SENSOR LOG";
...
 logText = logText + " Recnum: " + rec;

Thanks

strcat, strcpy and their cousins strncat, strncpy.

that causes heap overflow without any warning to the developer

I don't know many objects that do this - most just fail gracefully.

I've actually looked through the Arduino String implementation extensively. It pretty much does just what it advertises, just as one would expect. Any general-purpose string manipulation library is going to lead you to memory problems if used extensively in a memory-constrained environment.

You do have a point about the docs. The library docs for this should say, "String library considered harmful if used extensively. Arduino is not a great text-processing platform. Please use regular C string-manipulation functions wherever possible."

Ionito,

Yes, the String class is weak but it's not that the String class is to be blamed in this instance. Your program is garbage because it needs for such a simple task so many strings and your design is garbage because you failed to investigate how to properly handle static strings. Simply because you could program something the way you did in different environments doesn't mean it also applies to micro-controller with restricted RAM.

For a way to fix it, why not start with this post. Poof, all the memory problems are gone.

Also it's quite immature to come back whining about the evils of the String class while at the same time obviously not reading the answers to your previous question.

Korman

String was not designed with a microcontroller in mind, its just inappropriate for a limited memory device with no garbage-collection.

In general doing a lot of string bashing is a sign that you need a full processor with DRAM, rather than a microcontroller… If you can’t do it with sprintf perhaps it’s too much for the chip.

I had similar issues with a project I was working on. Didn't think it was terribly heavy in strings and string manipulation, but it was a good sized project and maybe the combination put it over the edge. So not to complain necessarily, but just to add a piece of anecdotal information FWIW. I didn't take the time to understand what was going on exactly, and certainly I could have been partly (or completely) at fault, but when I replaced the string functionality with strcat(), strcpy(), strcmp(), atoi(), etc., the problems went away. The String class is a bit more elegant, but the C functions are straightforward, so totally acceptable AFAIC, especially given the hardware limitations.

ionito:
I just would like to ask the community to give me simple examples to realize the total “String-wiping” from my existing code. For instance:

String logText = "SENSOR LOG";


logText = logText + " Recnum: " + rec;



Thanks

I tried that and it didn’t crash:

void setup ()
{
Serial.begin (115200);
int rec = 42;
String logText = "SENSOR LOG";
 logText = logText + " Recnum: " + rec; 
 Serial.println (logText);
 logText = logText + " Recnum: " + rec; 
 Serial.println (logText); 
}

void loop () {}

Output:

SENSOR LOG Recnum: 42
SENSOR LOG Recnum: 42 Recnum: 42

Now of course that would eventually crash if you loop adding to the string, what do you expect? But you need to provide a reproducible example that actually crashes then perhaps someone can fix it.

… this object (String) is so RAM-hungry that causes heap overflow without any warning to the developer.

I’m not sure what sort of warning you want. Looping consuming RAM isn’t something the compiler can predict. And at runtime there is no screen to put a “blue screen of death” on. About all a microprocessor can do when you trash RAM is loop or reboot. Sounds like yours is rebooting.

Personally I don’t use the String class because I am memory conscious. On the 328 chip I only have 2Kb of RAM to start with, and the program will be using some already for variables most likely. And heap fragmentation is a very real issue, and one hard to avoid.

Here’s an example… allocate 200 x 10 byte blocks of memory (ie. use up your 2000 bytes). Then delete every second one. So notionally you have 1000 bytes free. Then try to allocate a single 20 byte block. You won’t be able to because there is not a single 20 byte gap. So even with 1000 bytes of “free” memory you can do practically nothing with it. And string classes tend to do that, especially as you concatenate stuff (add to the end), which your example did. You have small strings, larger ones, even larger ones, etc.

You are asking to run out of memory if you do that.

Here is a test program that exercises the String class a bit:

String bar = "the question is not known";
int count1, count2;

void test ()
{
 String foo = "the answer is 42";
 if (foo == bar) 
   count1 ++; 
 if (bar == "the question is not known")
   count2 ++;
}

void setup ()
{
Serial.begin (115200);
for (int i = 0; i < 10000; i++)
  test ();
Serial.println ();
Serial.print ("count1 = ");
Serial.println (count1);
Serial.print ("count2 = ");
Serial.println (count2);
}

void loop () {}

That creates a local variable “foo” in the “test” function. Since it is a local variable it will be created every time through, thus causing memory allocations, and an assignment to the string. Then it does a couple of string comparisons.

The whole thing is done 10000 times, plenty of time to run out of memory. But it doesn’t, it runs to completion and prints the result.

So, sorry, sounds like you have a program bug. If you can provide a reproducible bit of code that demonstrates that the String class is faulty, please do.