Pages: [1] 2 3 ... 6   Go Down
Author Topic: The HATRED for String objects - "To String, or not to String"  (Read 11356 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Edison Member
*
Karma: 29
Posts: 2349
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've seen it so often now if as a whole the community is anti string to the extent it annoys members here...


Why not remove it (as in disable it as an option or something along the lines, default off you have to explicitly enable it somehow) ? obviously nobody likes it
instead replace it with a few handy char routines instead?
« Last Edit: September 26, 2012, 09:25:42 pm by cjdelphi » Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Why not remove it
Mostly because the problems are not all with the String class. Its design is fine. It is the implementation that leaves a bit to be desired. The real problem, though, is that the free() function has a fundamental flaw that needs to be addressed.

Once that is, the String class will be marginal. It will be fine for small strings - a dozen characters read from the serial port, for instance.

Quote
instead replace it with a few handy char routines instead?
Like strcat(), strcpy(), strtok(), strcmp(), you mean? These already exist, and are well documented, and can be used instead, today. No change needed.
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 91
Posts: 4690
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can get away with using the String Class with some care taken.. usually.

Problem is that many people don't know there's a reason to take care until it bites them, and then they post about a problem with crashes. You don't see many posts from people who managed to stay within limits, like the 2K RAM limit.

We will see a lot of this forever. People who learn C++ on PC's generally don't learn C strings and have no clue what goes on in the magic box let alone why a smaller box should be different.
Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 286
Posts: 25660
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I've seen it so often now if as a whole the community is anti string
No, not anti-string at all.

Very, very anti-String.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Reading, Berkshire
Offline Offline
Full Member
***
Karma: 2
Posts: 132
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Problem is that many people don't know there's a reason to take care until it bites them, and then they post about a problem with crashes. You don't see many posts from people who managed to stay within limits, like the 2K RAM limit.

This is what I have found. I've been trying to 'teach myself' how to code, I have no background in Electronics or coding. I see something like a string that seems to make sense if used in the way I want to use it. Two weeks later... no, start again. It breaks and I had no way of knowing why, or what to use instead.
Logged

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 91
Posts: 4690
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The big caveat with C strings is making sure you don't write past the end of the array. You -must- code for that yourself either explicitly or implicitly (like never writing any string too long, not good for general use but okay for special cases).

Set yourself up with some bookmarks, it's good to have references.

These are the library modules used in the AVR C++ Arduino uses:
http://www.nongnu.org/avr-libc/user-manual/modules.html

This is the C string library page:
http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html

You #include <string.h> to use those functions. All the names are shorthand, you get to know them.

Some easy basics you can do most simple things with:
strlen() is string length
strcpy() is string copy, it puts the terminating zero at the end of the copy. It is string = string.
strstr() is string string, it searches for a substring within a string
strcmp() string compare tells you if one string is >, ==, or less than another, good for sorting
strcat() string concatenation, adds one string to the end of another

You will some with an n in the middle. The n tells you that character count is used.

strncpy() is strcpy for up to n characters and does NOT put a zero at the end.
strncpy is perfect for writing over part of a string with another, in BASIC it is mid$()
 
Not simple but very useful is strtok(), string token, that you can use to parse strings with.

Also don't forget the mem (memory) functions, the 2 most basic:
memset(), to set some number of bytes equal to a given value
memmove(), copies bytes and **is safe to use when the destination overlaps the source**

There's more of all of them. And if you don't see what you want then remember that C strings are just 1 dimension byte arrays you can easily process in loops without needing any library whatsoever. Those functions are only for convenience once you understand how C strings work.

One function C strings don't have that C++ String Class does is a function to tell you where the data actually is. That's because with C strings you don't one, ^^ YOU tell the function where the data is and where it goes ^^ and IT doesn't go anywhere else, unlike mind-of-their-own String objects.

Hope this helps with your jitters. The territory is really quite simple and rock solid stable.
Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Offline Offline
Newbie
*
Karma: 0
Posts: 12
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Me, I love strings. Use them all the time and never have a problem with them. I hate chars.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Why not remove it (as in disable it as an option or something along the lines, default off you have to explicitly enable it somehow) ?

Instead of removing strings, they just have to make about a 1-line change to the library code in free() that has a bug in it. Then some, at least, of the problems will go away.

You potentially still have problems with memory fragmentation, but as some posters have observed, these do not always bite you.
Logged

UK
Offline Offline
Shannon Member
****
Karma: 222
Posts: 12520
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If stability is important then I don't think it is a good idea to use dynamic memory allocation on systems without a robust memory management system, unless you understand the patterns of allocation and deallocation that will occur. I doubt that it would ever be practical to implement a generally robust memory management system within the constraints of an Arduino.

At the same time, dynamic helper classes such as String are IMO going to be particularly useful to novices because they take away the pain of dealing with buffers and points and so on. So the people most likely to use this are also the ones least likely to understand when and how to use dynamic allocation safely.

 Given that one of the main goals of Arduino seems to be to make development accessible to novices, this strikes me as a step in the wrong direction.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

0
Online Online
Shannon Member
****
Karma: 199
Posts: 11642
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Problem is that many people don't know there's a reason to take care until it bites them, and then they post about a problem with crashes. You don't see many posts from people who managed to stay within limits, like the 2K RAM limit.

This is what I have found. I've been trying to 'teach myself' how to code, I have no background in Electronics or coding. I see something like a string that seems to make sense if used in the way I want to use it. Two weeks later... no, start again. It breaks and I had no way of knowing why, or what to use instead.

The problem with the String class on the Arduino is that it assumes sophisticated memory management (like a reference-counting or other garbage-collector).  You don't have that on a 2K microcontroller, so eventually intermediate results (usually of string-concatenation) bung up memory and the processor crashes.   Compilers cannot analyse every possible execution of your code so they cannot determine every case of where a String object becomes unreferenced and thus can be freed.

Using char * rather than String forces the programmer to handle string lifecycles and memory allocation, and the programmer usually knows how the program is mean to run and when a char array can be reused.

Compare with the String class in the Java language - this does have a garbage-collector to recover dead objects so you can have nice intuitive String operations and memory runs out only if you genuinely are hanging on to too much stuff - you never have to call free() and it all just works.  But that runs on systems with MB of RAM and ROM...
Logged

[ I won't respond to messages, use the forum please ]

Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 91
Posts: 4690
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What Nick said, a small fix to free() would do wonders for use of the String class.

Just plain 'strings' aren't a problem at all. It's the Strings that trip so many people up.

Quote
Using char * rather than String forces the programmer to handle string lifecycles and memory allocation, and the programmer usually knows how the program is mean to run and when a char array can be reused.

It forces an MCU programmer to know about the hardware which is blasphemy to purist comp-sci dweebs. How many programmers does it take to change a light bulb? Can't be done, it's a hardware problem!

Logged

I find it harder to express logic in English than in Code.
Sometimes an example says more than many times as many words.

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 474
Posts: 18696
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm going to agree with GoForSmoke here. Tests in other threads have shown that, with free() fixed, code that previously crashed regularly worked indefinitely.

Whilst is it possible to fragment and run out of memory with only 2 Kb to spare, code that allocates (and then frees) the same sizes strings all the time will not suffer from it.

In particular, if you avoid doing string concatentation which is probably the worst offender in causing fragmentation. (That is, building up a string by adding one character to it all the time). In any case, this sort of string-building is necessarily slow.
Logged

South Texas
Offline Offline
Edison Member
*
Karma: 8
Posts: 1024
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The main problem with Strings is, with a limited RAM machine the potential to have a problem because you didn't properly account for how (worst case) memory might be used, and how you will deal with the condition that results. On small, simple programs you won't see much problem, but as the programs grow the need for total memory management BY THE PROGRAMMER becomes more and more the major requirement. One call to a function that uses Strings without having memory properly cleaned up and things crash. Is that the fault of Strings, or bad programming practice by a programmer that didn't keep track of his free memory.

It is interesting to note that in the early days all programmers had memory usage tables and when they wrote a program they documented exactly how memory would be used because it was tight. Once again we are using a system with tight memory constraints and we expect the software to do the programmers job. If you want unlimited memory, don't use an arduino.

Oh - it wasn't all that many years ago that there existed machine with 4Kx8bit memory, for program AND data and we made it work... 16K x 8 bit cost $80.00 US.
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17259
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Oh - it wasn't all that many years ago that there existed machine with 4Kx8bit memory, for program AND data and we made it work... 16K x 8 bit cost $80.00 US.

And before that in the minicomputer era a 16K x 16 bit core memory board would set you back some thousands of dollars.

Lefty
Logged

Offline Offline
Edison Member
*
Karma: 29
Posts: 2349
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

For example
void loop()
{
  char c[10];
  int n;


}

//what happens exactly here

with each iteration of the loop does a local variable get created (c/n) and recreated over and over again?... at the time i did not know so I simply made a global var c/n (but whatever i called them in my project)
so i knew i was never going to fill the memory full of undestroyed pointers and unused memory allocations (just to be on the safe side)

so with each loop would all the local variables be destoyed along with any memory allocation?
Logged

Pages: [1] 2 3 ... 6   Go Up
Jump to: