Pages: 1 [2]   Go Down
Author Topic: Memory leak in WString / TextString Library?  (Read 3632 times)
0 Members and 1 Guest are viewing this topic.
New York, NY, USA
Offline Offline
Newbie
*
Karma: 0
Posts: 40
Howdy. I don't check PMs often, so email me!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I just posted version 0.7 of the String lib, which is basically the bug fix Mikal Hart posted.  Sorry for the long delay. String is not part of the core, so it's always been a side project for me, and one I only get to once in a blue moon. The memory bug,at least, should now be gone. Thanks Mikal.

This is an interim version. Hernando Barragan made some nice API changes for a Wiring version, but they change the core libraries a bit, and have not yet been ported over fully. There are also some changes I want to make, because there's some nomenclature and behavior I'm not happy with.   Xiaoyang Feng is working on this.  The major issue he's working on is to make the library portable without need to modify the core, and to reduce memory usage somewhat.  If anyone wants to jump in on this task, mail me.
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
I just posted version 0.7 of the String lib

Where might I find the link/posting for this new version?

Thanks;
Lefty
Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 388
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Lefty, it looks like it's linked off of http://www.arduino.cc/en/Tutorial/TextString.

The page history shows it was updated today, and the WString.h file in the .ZIP file reflects version 0.7.
« Last Edit: March 29, 2010, 04:44:38 pm by TBAr » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 8
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Destructor need inicializate vars:

Code:
String::~String() {
      free(_array);
      _capacity = 0;
      _length = 0;  
}
http://www.megaupload.com/?d=7TAT552N


Do you lost memory with substring?
« Last Edit: June 18, 2010, 09:29:30 am by scrambler » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Many thanks for this thread. It has helped a very frustrating problem!


But once I place the destructor in my code (or download the new zip...same thing), it doesn't function the same any more. Here's the relevant code:
Code:
void somefunction()
{
  char* timestamp = isoTimestamp();
  
  Serial.println(timestamp);
}


// iso8601 timestamp of current time
char* isoTimestamp(){
  Serial.println("in isoTimestamp");
  time_t t = now();

  Serial.println("Allocating String(20)");
  String str = String(20);

  Serial.println("Formatting timestamp");
  str.append(year(t));
  str.append("-");
  if(month(t) < 10) str.append("0");
  str.append(month(t));
  str.append("-");
  if(day(t) < 10) str.append("0");
  str.append(day(t));
  str.append("T");
  if(hour(t) < 10) str.append("0");
  str.append(hour(t));
  str.append(":");
  if(minute(t) < 10) str.append("0");
  str.append(minute(t));
  str.append(":");
  if(second(t) < 10) str.append("0");
  str.append(second(t));
  str.append("Z");

  Serial.print("isoTimestamp: ");
  Serial.println(str);
  
  char* outputChars = str.getChars();

  Serial.print("char isoTimestamp: ");
  Serial.println(outputChars);

  return str;
}

The above prints:
in isoTimestamp
Allocating String(20)
Formatting timestamp
isoTimestamp: 2010-06-22T23:33:23Z
char isoTimestamp: 2010-06-22T23:33:23Z
+?10-06-22T23:33:23Z

Note the two first bytes in the returned char* are wrong/odd (it isn't really a '?', but it was interpreted as a newline in the forum post). This occurs whether I "return str;" or "return str.toChars();"

I'm still pretty new to Arduino, and haven't messed with C-based stuff (aka pointers) since college long ago, so hopefully this is just a newbie mistake. But it worked fine before adding the String destructor. Well, other than the memory leak, anyway! Can someone help?

Thanks in advance.
« Last Edit: June 22, 2010, 06:44:14 pm by ntovsen » Logged

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

In the isoTimestamp function, you have:
Code:
String str = String(20);
.
.
.
  return str;
str is a local variable. It does out of scope at the end of the function. And, yet, you return a pointer to internally allocated memory of that string. The memory no longer is reserved by the variable (because the variable is out of scope). The memory was released, but has not yet been entirely) overwritten.

You could have isoTimestamp return the output of the strdup function, which allocates memory and copies the string:

Code:
return strdup(str);
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 155
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I used the new library download and mine still freezes.  Takes about 20min running the following code.  Any suggestions?
I leave the webpage open and it refreshes the get8 and get3 every 2 seconds.



Code:
#include <WString.h>
#include <Ethernet.h>
#include <stdlib.h>
byte mac[] = { 0x00, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 1, 30 }; // MY IP change to your needs
Server server(80);
String readString = String(100);


void setup(){
  
  Serial.begin(9600);
  pinMode(8, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(3, OUTPUT);
  Ethernet.begin(mac, ip);
  digitalWrite(7, HIGH);
}

void loop(){
  Client client = server.available();
  if (client)
  {
    while (client.connected())
    {
      if (client.available())
        {
        char c = client.read();
        if (readString.length() < 100)
            {
            readString.append(c);
          }
        if (c == '\n')
            {
              //code for pin 8
            if(readString.contains("toggle8"))
                {
              toggle(8);
                  //client.println("<html><head>");
                  //client.println("<meta http-equiv=REFRESH content=0;url='http://192.168.1.31/frontend.php'>");
                  //client.println("</head></html>");
                }
              if(readString.contains("get8")){
          // Now output HTML data starting with standart header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          //client.println("led 8 is");
            //client.println(digitalRead(8));
            if(digitalRead(8) == 0){
              client.print("<IMG SRC=images/lightoff.png>");}
              else if(digitalRead(8) == 1){
              client.print("<IMG SRC=images/lighton.png>");}
            Serial.println("pin 8 is");
            Serial.println(digitalRead(8));
              }
        
            //code for pin 3
            if(readString.contains("toggle3"))
                {
              toggle(3);
                  //client.println("<html><head>");
                  //client.println("<meta http-equiv=REFRESH content=0;url='http://192.168.1.31/frontend.php'>");
                  //client.println("</head></html>");
                }
            if(readString.contains("get3")){
          // Now output HTML data starting with standart header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          //client.println("led 8 is");
            //client.println(digitalRead(3));
            if(digitalRead(3) == 0){
              client.print("<IMG SRC=images/lightoff.png>");}
              else if(digitalRead(3) == 1){
              client.print("<IMG SRC=images/lighton.png>");}
            Serial.println("pin 3 is");
            Serial.println(digitalRead(3));
              }
            
            
            
            
            readString="";
          client.stop();
            
              }
            }
        }
      }
    
  
}
 
 int toggle(int pinnumber){
  if(digitalRead(pinnumber) == HIGH){
    Serial.print("toggle functions says ");
    Serial.print(pinnumber);
    Serial.print(" is on");
    Serial.println();
    // if light is on turn it off
    digitalWrite(pinnumber, LOW);
    return(0);
  }
  if(digitalRead(pinnumber) == LOW){
    Serial.print("toggle functions says ");
    Serial.print(pinnumber);
    Serial.print(" is off");
    Serial.println();
    // if light is off turn it on
    digitalWrite(pinnumber, HIGH);
    return(0);
  }
}

Logged

Pages: 1 [2]   Go Up
Jump to: