string or String.... which is the preferred way?

I know there are two ways of making strings. One is the string (small-s) which is an array of data type chars; other is the String (capital-S) which is a data type in its own right.

Does it matter which approach I use? Is one better than the other in certain circs?

TIA as always,

Jim

String - the object uses dynamic memory that makes Swiss chess of your memory (aka fragmentation). On platforms with substantial more memory than 2K this is not a problem, but for an UNO it can seriously fragment the memory.

I prefer string == char[] and low level c functions like strcpy() etc as one can control the memory use far better.

The String (object) has a number of nice functions that makes it easy for parsing. The String uses string internally.

Thanks Rob.... my question came about because of the parsing thing.

I've seen web server sketches handling the HTTP requests both ways, and String certainly does look easier. But if it runs out of memory I don't suppose it matters how easy it is....

JimboZA: I've seen web server sketches handling the HTTP requests both ways, and String certainly does look easier. But if it runs out of memory I don't suppose it matters how easy it is....

If you run across any of those you can't translate to be suitable for char arrays, you have this forum to ask. Yes, some operations can be a little longer to write, but when you do once, you'll always have them (you DO save useful snippets, right?) , and you can re-use them.

you DO save useful snippets, right?

I've still got my first Fortran Job card from 1974.....

Until recently, there was really only one person regularly defending the use of String and it always used to remind me of an exchange between Edmund Blackadder and Captain Redbeard Rum:

BLACKADDER I was under the impression that it's common maritime practice for a ship to have a crew. CAPTAIN RUM Opinion is divided on the subject; all the other captains say you do, I say you don't.

Of late there have been a couple of other String proponents, but the prevailing view is to avoid them like the plague on the small arduinos.

my question came about because of the parsing thing.

People wrote extensive test handling applications for decade before the String class was developed. The strtok() function is the heart of any parser.

As has been mentioned, the String class uses only strxxx() functions to search the string that it wraps (I almost typed warps). You can look at the source for the String class to see how it (easily) implements any method that you would like to use on your string.

So, effectively the String is just doing with a more user friendly face, exactly what I can do "long-hand" so to speak, and the cost of the friendly face is the memory use?

JimboZA: So, effectively the String is just doing with a more user friendly face, exactly what I can do "long-hand" so to speak, and the cost of the friendly face is the memory use?

Since I know how to do string processing, I don't see the String class as having a "more user friendly face". YMMV.

JimboZA: So, effectively the String is just doing with a more user friendly face, exactly what I can do "long-hand" so to speak, and the cost of the friendly face is the memory use?

Pretty much. Similar to using windows as a shell to run dos instead of keyboarding with dos itself. I'd like to hear a technical explanation of the memory fragmentation "swiss cheese" using Strings that wouldn't happen using c-strings and declared memory space. The c-string proponents say use something like myBigArray[128], but they probably don't actually have a clue how or where this memory space will be assigned in the chip memory registers, or how it may impact other memory use operations.

The c-string proponents say use something like myBigArray[128], but they probably don’t actually have a clue how or where this memory space will be assigned in the chip memory registers, or how it may impact other memory use operations.

Oh, yes, we do.

PaulS:

The c-string proponents say use something like myBigArray[128], but they probably don't actually have a clue how or where this memory space will be assigned in the chip memory registers, or how it may impact other memory use operations.

Oh, yes, we do.

zoomkat, you walked right into that one..... :P

JimboZA:

PaulS:

The c-string proponents say use something like myBigArray[128], but they probably don't actually have a clue how or where this memory space will be assigned in the chip memory registers, or how it may impact other memory use operations.

Oh, yes, we do.

zoomkat, you walked right into that one..... :P

Well, if you and PaulS can actually specify the exact page/word memory locations that specific arrays will be placed in prior to uploading the code, then my bad. :( Otherwise let me offer you a Kleenex.

I am a String user on an Ethermega card with 8KB RAM.

After two days five hours and 19 minutes my application's "swiss cheese" free heap list is just 532 bytes comprising six free heap data blocks of these sizes - 322, 163, 25, 12, 5, 5.

At a previous point in my application development the free heap list typically ran very much smaller. I hope to get back to that by converting some global String variables to strings[].

It is all largely irrelevant in terms of memory utilisation and management - when my application is reading or writing out SD card data while serving up a web page total heap memory utilisation runs up to about 2K. Eliminating the use of Strings is not going to eliminate other dynamically created memory objects and buffers used within the SDFat (SD Card) and Ethernet libraries. I might as well use Strings which as dynamically created objects will also use the widely varying in size/utilisation heap memory.

At this time my application's free memory seems to range between 1K and 3K depending on what it is doing and very little of that relates to Strings and I see no evidence that Strings create a lot of swiss cheese free heap memory.

On my Arduino application's web site at http://219.88.69.69/2WG/ you can see RAM usage statistics. Those stats are reset everyday - so what you see if maximums and minimums since midnight (plus the current situation).

Catweazle NZ

CatweazleNZ: It is all largely irrelevant in terms of memory utilisation and management - when my application is reading or writing out SD card data while serving up a web page total heap memory utilisation runs up to about 2K. Eliminating the use of Strings is not going to eliminate other dynamically created memory objects and buffers used within the SDFat (SD Card) and Ethernet libraries. I might as well use Strings which as dynamically created objects will also use the widely varying in size/utilisation heap memory.

IMO, this is the crux of the debate right here. With all the objects being created and destroyed in largely OOP-based libraries, I don't know why String in particular gets so much hate. It doesn't seem fair to call out one example of dynamic allocation -- well, I got some heat for defending malloc() too, so I guess there are actually a couple. I assume the intent is based on low-hanging fruit, but why aren't there more suggestions to move object initialization into setup() when using files from SD cards, or other short-lived objects for example?

ANY dynamically allocated memory has the potential to fragment memory. If all memory is always allocated, then deallocated, in FILO order, there is no fragmentation, ever. Otherwise, there is fragmentation. If ever during the course of your application's runtime, all dynamically-allocated memory is freed, then you start with a clean slate again. AFAIC, that's the only thing you need to know.

Use String, use char[], use malloc(), whatever. If you know you'll be creating strings (any) dynamically, and their lifetimes will vary, it might be better to create a pool of adequately-sized char[] arrays and assign them as needed. OTOH, if you call a function, create a string, use the string, then it falls out of scope when you exit that function, then it doesn't much matter what you use. Unless, of course, you also have memory allocation happening via an interrupt.

Finally, no one cares where in memory blocks are allocated, that's not relevant. (Usually. I'm sure someone will provide an example otherwise.) The only thing that matters is the order in which they and all following blocks are allocated, and then deallocated. Nevermind, that's just asking for it. :) Heap vs. stack springs to mind immediately.

CatweazleNZ, I'm wondering why your bathroom light's on at 4 o'clock on a summer arvie? 8)

JimboZA: CatweazleNZ, I'm wondering why your bathroom light's on at 4 o'clock on a summer arvie? 8)

That web page is just a proposed development - none of the displayed values are active.

Eveything else on every other page is active - except the PIRs that show a 0:00:00 time on the Security page. So far I have only installed the one PIR installed in the Lounge - I have the others - just need to get into the ceiling and run the wires everywhere.

Good spotting.

Cheers

Catweazle NZ

Very nice implementation btw, CNZ. And yes your security works: it shows the directory contents but can't open the files.

JimboZA: Very nice implementation btw, CNZ. And yes your security works: it shows the directory contents but can't open the files.

You did not test the security much? For example you did not try to guess the password.

This would be you I presume:

16:06:15 GET /2WG/ HTTP/1.1 (41.132.16.87) [43943]
16:06:15 HOST 219.88.69.69
16:07:00 GET /17823/ HTTP/1.1 (41.132.16.87) [17823]
16:07:00 HOST 219.88.69.69
16:12:48 GET /17823/ HTTP/1.1 (41.132.16.87) [17823]
16:12:48 HOST 219.88.69.69
16:13:05 GET /43039/ HTTP/1.1 (41.132.16.87) [43039]
16:13:05 HOST 219.88.69.69
16:13:23 GET /BACKUPS.DIR/ HTTP/1.1 (41.132.16.87) [/SDCard//BACKUPS/]
16:13:23 HOST 219.88.69.69
16:13:45 GET /43034/ HTTP/1.1 (41.132.16.87) [43034]
16:13:46 HOST 219.88.69.69

Cheers

Catweazle NZ

Yeah that's me- hey it was 530 in the morning...