Reducing sketch sizes, 6 lines causes 1K bytes of program space

I’m trying to reduce the sketch size of my program and I have narrow them to these six lines consist of a String …

These 6 lines of codes takes up 964 Bytes of storage space…

Can anyone help to explain why this happens ??

With the 6 lines of codes :-

Sketch uses 25,220 bytes (82%) of program storage space. Maximum is 30,720 bytes.
Global variables use 1,205 bytes (58%) of dynamic memory, leaving 843 bytes for local variables. Maximum is 2,048 bytes.

Without the 6 lines of codes :-

Sketch uses 24,256 bytes (78%) of program storage space. Maximum is 30,720 bytes.
Global variables use 1,199 bytes (58%) of dynamic memory, leaving 849 bytes for local variables. Maximum is 2,048 bytes.

     String cmtOut = "";

       cmtOut.concat("@");
       cmtOut.concat(padding((int) gps.course.deg(),3));
       
       cmtOut.concat("/");
       cmtOut.concat(padding((int)gps.speed.mph(),3));
       
       cmtOut.concat("/A=");
       cmtOut.concat(padding((int)gps.altitude.feet(),6));
       
       cmtOut.concat(" Seq:");
       cmtOut.concat(txCounter);



String padding( int number, byte width ) {
  String result;
  
  // Prevent a log10(0) = infinity
  int temp = number;
  if (!temp) { temp++; }
    
  for ( int i=0;i<width-(log10(temp))-1;i++) {
       result.concat('0');
  }
  result.concat(number);
  return result;
}

String class uses a lot of memory.

use C strings (char arrays) instead and save all the space you need.

I'm not so good at strings manipulation and therefore uses String class as a shortcut ...

Is using sprintf() a good alternatives ??

I just need to append characters or sensor values to a long C strings before sending it out over to the serial ..

sprintf() is a very flexible way to proceed, but it will use up a fair amount of memory too. There are a bunch of standard routines that use less space. For example, to concatenate strings, you can use strcat(). To convert integers to ASCII format, you can use itoa(), etc.

Here is a description of string (zero-terminated character array) operators: http://www.tutorialspoint.com/c_standard_library/string_h.htm

I'm not so good at strings manipulation and therefore uses String class as a [u]shortcut[/u]

You misspelled crutch. Either live with the space being wasted, or get better at string manipulation. It is NOT hard.

PaulS: You misspelled crutch. Either live with the space being wasted, or get better at string manipulation. It is NOT hard.

Hahaha, that is a good one ...

Still learning and improving my C programming ...

Stanley: I'm not so good at strings manipulation and therefore uses String class as a shortcut ...

There ain't no such thing as a free lunch

Things like the String C++ class and the sprintf function do a lot of useful stuff at the price of being memory and processor intensive.

For computers with gigabytes of memory, this is not a problem. For an Arduino, however, it is. So we have to go back to old-school ways of doing things. This means that we have to use a number of small, specific functions that only do one thing and construct what we want out of that.

According to the Arduino homepage

The Arduino language is based on C/C++. It links against AVR Libc and allows the use of any of its functions; see its user manual for details.

The user manual for AVR libc is here: http://www.nongnu.org/avr-libc/user-manual/index.html

And the page on string functions is here: http://www.nongnu.org/avr-libc/user-manual/group__avr__string.html

Ok,

I need a function of search and add if the string do not exist in the array

Search an existing char array for a string ( 9xaaa-12 ) , only append the callsign if it is not in the char array..

Any pointers/hints of which string functions should I use for this purposes ..

current char array : 9xaaa-12/12km 9xbbb-9/4km

new callsign: 9xaaa-12 ( only add if it is not found in the string )

I'm currently using String class of rxCallsign.startsWith(call) but it is not working ....

Search an existing char array for a string ( 9xaaa-12 ) , only append the callsign if it is not in the char array..

That's quite a bit more challenging than it appears. The issue is that your program will have a certain amount of memory allocated for the string. If you just append stuff after it, this will possibly clobber other things.

So you need to do this in a temporary space, or use malloc() to create the memory (which I don't recommend), or be sure that your string is in an array that already has enough space in it.

If you have read the string in from somewhere, then it will be sitting in a buffer of a certain length, and that buffer might be long enough to make it safe to append the string.

Here's a sketch that should show you what I mean.

char array1[] = "this is the first array";
char array2[] = "this is the second array";
char array3[] = "this is the third array";

char *string1 = "this is the first string";
char *string2 = "this is the second string";
char *string3 = "this is the third string";

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

  // pause for 5 secs to give me a chance to put the serial monitor up
  for (int i = 5; i >= 0; i--) {
    delay(1000);
    Serial.print(' ');
    Serial.print(i);
  }
  Serial.println();

  print_all_the_strings();
  
  strcat(array2, "[CALLSIGN X]");
  strcat(string2, "[CALLSIGN Y]");

  print_all_the_strings();
}

void print_all_the_strings() {
  Serial.print("array 1: "); Serial.println(array1);
  Serial.print("array 2: "); Serial.println(array2);
  Serial.print("array 3: "); Serial.println(array3);
  Serial.println();

  Serial.print("string 1: "); Serial.println(string1);
  Serial.print("string 2: "); Serial.println(string2);
  Serial.print("string 3: "); Serial.println(string3);
  Serial.println();
}

void loop() {
  // put your main code here, to run repeatedly:

}

I would suggest also checking whether those gps accessor functions are unnecessary.

Thanks for the replies ...

After a few searches, I found this possible solution to search using strstr()

http://stackoverflow.com/questions/12784766/check-substring-exists-in-a-string-in-c

Matches callsign strings in an existing buffer strings

if(strstr(buffer, callsign) != NULL) {

    strcat(buffer,callsign);
    ...

}