Ashish Sharma
Ashish Sharma

Reputation: 1196

String reference not updating in function call in C++

I am writing an arduino library to post http request on web.

I am using the String class from http://arduino.cc/en/Tutorial/TextString

My code is behaving strangely when I am referring to my defined string objects after a function call.

Here actually I am trying to get the body of my GET request and removing the http headers from the http GET request's response.

Following is the description:

Method Call:

  String body;  
  if(pinger.Get(host,path,&body))
  {
    Serial.println("Modified String Outside :");
    Serial.println(body);
    Serial.println();
    Serial.println("Modified String Outside Address");
    Serial.println((int)&body);
  }

Output

Modified String Outside :
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html
Content-Length: 113
Date: Wed, 13 Jan 2010 14:36:28 GMT

<html>
<head>
<title>Ashish Sharma
</title>
</head>
<body>
Wed Jan 13 20:06:28 IST 2010
</body>
</html>


Modified String Outside Address
2273

Method Description:

bool Pinger::Get(String host, String path, String *response) {
    bool connection = false;
    bool status = false;

    String post1 = "GET ";
    post1 = post1.append(path);
    post1 = post1.append(" HTTP/1.1");

    String host1 = "Host: ";
    host1 = host1.append(host);

    for (int i = 0; i < 10; i++) {
        if (client.connect()) {
            client.println(post1);
            client.println(host1);
            client.println();
            connection = true;
            break;
        }
    }

    int nlCnt = 0;
    while (connection) {
        if (client.available()) {
            int c = client.read();
            response->append((char) c);
            if (c == 0x000A && nlCnt == 0) {
                nlCnt++;
                if (response->contains("200")) {
                        status = true;
                        continue;
                    } else {
                        client.stop();
                        client.flush();
                        break;
                    }   
            }
        }
        if (!client.connected()) {
            client.stop();
            connection = false;
        }
    }           
    response = &response->substring(response->indexOf("\n\r\n"),response->length());    
    Serial.println("Modified String: ");
    Serial.println(*response);  

    Serial.println();
    Serial.print("Modified String Address: ");
    Serial.println((int)&response);
    return status;
}

Output:

Modified String: 
Ø
<html>
<head>
<title>Ashish Sharma
</title>
</head>
<body>
Wed Jan 13 20:06:28 IST 2010
</body>
</html>

Modified String Address: 2259

As can be seen from the example the string reference object is giving me the correct string inside the Get method but the reference of the string contents change when the Get method returns.

Upvotes: 3

Views: 1310

Answers (3)

josefx
josefx

Reputation: 15656

The line

 Serial.println((int)&response);

inside your function is wrong response is already a pointer (String * response), with &response you get the pointer to the pointer.
Change it to

Serial.println((int)response);

and you should get the same address as with

 Serial.println((int)&body);

where body is a String and &body is the pointer to the string

Upvotes: 1

Iustin Amihaesei
Iustin Amihaesei

Reputation: 116

If I understood correctly your code, you probably would want to do something like this:

*response = response->substring(response->indexOf("\n\r\n"),response->length());

instead of

response = &response->substring(response->indexOf("\n\r\n"),response->length());

Also there's probably no need to pass in a pointer ( reference would probably make the code look much nicer ).

Upvotes: 3

Konrad Rudolph
Konrad Rudolph

Reputation: 545766

First off, you are modyfying the address of the string, not the string itself. But the address of the string was passed to the function by value, and thus copied. Modifying it inside the function won’t modify it on the outside.

Secondly, this code here is bad:

response = &response->substring(response->indexOf("\n\r\n"),response->length());

Because it creates a pointer to a temporary object – which means: a dangling pointer because the temporary object will be destroyed after the expression has been evaluated.

What you really want is pass the object by reference (String& response) and modify it, not its pointer:

response = response->substring(response->indexOf("\n\r\n"),response->length());

This should work, provided the String class you use correctly overloads the behaviour of the assignment operator =.

Upvotes: 3

Related Questions