Pages: 1 2 [3] 4 5 6   Go Down
Author Topic: The HATRED for String objects - "To String, or not to String"  (Read 9979 times)
0 Members and 1 Guest are viewing this topic.
Pittsburgh, PA, USA
Offline Offline
Faraday Member
**
Karma: 58
Posts: 4020
I learn a bit every time I visit the forum.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

For most cases this will result in no pointer change at all and a simple adjustment of the allocated length - usually out into free space in most use-cases on a small system like this.

Assuming the String is at the top of the heap in 'most cases'. Otherwise not.

Andy Brown, I think you will find that Nick knows more about the code than you credit. And he isn't given to make unfounded claims.

Logged

Examples can be found in your IDE.

0
Offline Offline
Tesla Member
***
Karma: 116
Posts: 8944
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So is there anything in the external programming that can be done to free the no longer used allocated memory space?
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

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

So is there anything in the external programming that can be done to free the no longer used allocated memory space?

Perhaps enable the WDT, let if time out, and have the sketch start all over?  smiley-grin
Logged

0
Offline Offline
Tesla Member
***
Karma: 116
Posts: 8944
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Perhaps enable the WDT, let if time out, and have the sketch start all over? 

Close to what my magic 8-Ball suggested.  smiley
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Andy Brown, I think you will find that Nick knows more about the code than you credit. And he isn't given to make unfounded claims.

I don't have any argument with Andy. I think he has the fixed malloc/free library on his site anyway.

There is a bug in 'free' in the current Arduino library. I think we are all agreed on that. What Andy says about free spaces being combined by the library would almost certainly be correct. But the bug in question is something to do with the first (or last?) allocated block not being freed correctly, or something like that.

I have heard people say that, with the fixed free() installed, they can use String objects at some length with no problems, which supports what Andy says about the library combining unused blocks.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So is there anything in the external programming that can be done to free the no longer used allocated memory space?

In one of the threads about this problem I suggested incorporating the corrected free function into existing code, and having a define along the lines of:

Code:
#define free myfree

in one of the header files that gets pulled into all libraries (including the String library). For the sake of a few dozen extra instructions you then have a workaround until the real library is fixed.
Logged

0
Offline Offline
Tesla Member
***
Karma: 116
Posts: 8944
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But the bug in question is something to do with the first (or last?) allocated block not being freed correctly, or something like that.

Then is there any way in the code to keep that particular block filled with nothing?
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

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

I took what Andy wrote to be saying there is no bug/problem. My error.
Logged

Examples can be found in your IDE.

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 53
Posts: 1790
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

global variables work better for me and I haven't heard of a good reason I should avoid them in my Arduino sketches.
Lefty

I can share at least one reason why you should reconsider globals. Here is a little sketch showing how a global can cause a very bad day.

This calculates the square of 2.

Code:
   //A global
   int i = 666;
 
   template <typename T> struct Base{
     Base( int i_NewVal ) : i( i_NewVal ) {return;}
     int i;
   };
   
   template <typename T> struct Squared : public Base<T>{
     Squared( int i_NewVal ) : Base<T>( i_NewVal * i_NewVal ) {return;}
     T Result() { return i; }
   };

  void setup()
    {
      Squared< long > s_Square( 2 );
     
      Serial.begin( 9600 );
      Serial.print( "2 squared = " );
      Serial.print( s_Square.Result() );
      return;
    }
   
  void loop(){return;}
Logged


Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
   int i = 666;

I haven't even tried to run your sketch, but straight away, I sense trouble. smiley-wink
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@pyro

You sketch is not about globals, rather it warns of the perils one faces by using poorly named variables smiley
Logged

North Queensland, Australia
Offline Offline
Edison Member
*
Karma: 53
Posts: 1790
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The name of the variable could be something intuitive, I used 'i' for this example.
It does not affect the example. The sketch below works fine.

Code:
   //A global
   int i = 666;
 
  void setup()
    {
      int i = 2 * 2;
     
      Serial.begin( 9600 );
      Serial.print( "2 squared = " );
      Serial.print( i );
      return;
    }
   
  void loop(){return;}

In my previous example,
The global is a non-dependant name, it is satisfying a rule where non-dependant names in dependant types take the last definition seen. The compiler doesn't consider the base class during name lookup, even though its 'i' is the closer scope. This is quite different to the snippet above where the closer scope is setup::i which is also used.

So rather than receiving an error about 'i' being undefined in the class ( 'this->' is required to make the name dependant ), the previous definition of 'i' is silently used.

As a minimum, place the global in a namespace so it has to be explicitly used.
Logged


Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
As a minimum, place the global in a namespace so it has to be explicitly used.

Very interesting posts. I would add as a minimum don't go against common practices by naming a global with a name usually "reserved" for narrow-scoped counters and array indexes. IOW, don't produce code that's confusing to _read_ in the first place. smiley
Logged

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

Quote
You sketch is not about globals, rather it warns of the perils one faces by using poorly named variables
I see it more as a problem with having local and global variables with the same name, and making assumptions about which will be used when.

Having local and global variables of the same name is rarely a good idea.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I going to agree with PaulS here. In your (rather obscure) example pYro_65 you set up a case where the compiler chose a global instead of a class variable by using the same name for both. To fix the sketch BTW you need to change the derived class to:

Code:
template <typename T> struct Squared :
public Base<T>{
  Squared( int i_NewVal ) :
  Base<T>( i_NewVal * i_NewVal ) {
    return;
  }
  T Result() {
    return Base<T>::i;
  }
};

Notice the qualification of "i" there. But you could say the same thing about virtually any variable. If you had a global i_NewVal and then misspelt i_NewVal in the constructor you would have a similar issue.
Logged

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