Problem with the "String.toCharArray()"

Hi guys, I'm trying to parse a json response from my web api:

This is a chunk, here I send the GET request, and I capture the response from the server:

 if (client.connect(server, 80)) {
    //Send the HTTP Request
    Serial.println("Fetching Data...");
    Serial.println();
    client.println("GET "+path+" HTTP/1.1");
    client.println("Host: localhost");
    client.println("User-Agent: ArduinoWiFi/1.1");
    client.println("Connection: close");
    client.println(); 

    //Capture the response
    while (!rcvResponse){
      if (client.available()){
        rcvResponse=true;
        while (client.available()){
          char c = client.read();
          http_response += c;  
        }
      }
    }

    client.stop();

    Serial.println("Website response STRING: ");
    Serial.println(http_response);
    Serial.println();

This is the output in JSON:

Website response STRING:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 195
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 24 Nov 2014 14:33:11 GMT
Connection: close

{"Success":true,"ErrorDescription":null,"ErrorCode":null,"Data":{"DaysList":[{"EventId":2,"DayId":5,"NumberOfVisitors":0,"Done":false},{"EventId":2,"DayId":6,"NumberOfVisitors":0,"Done":false}]}}

Then I try to parse the response, in this way:

    char httpJSON[http_response.length()+1];
    http_response.toCharArray(httpJSON, http_response.length()+1);   

    Serial.println("Website response CHAR-ARRAY: ");
    Serial.write(httpJSON);
    Serial.println(); 

    aJsonObject* root = aJson.parse(httpJSON);

    if (root != NULL) {
      Serial.println("OK: JSON Object obtained");
    }
    else{
      Serial.println("ERROR: Unable to get the root.");
    }

And then, the output:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 195
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 24 Nov 2014 14:33:11 GMT
Connection: close

{"Success":true,"ErrorDescription":null,"ErrorCode":null,"Data":{"DaysList":[{"EventId":2,"DayI´×þûHTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 195
Content-Typ
ERROR: Unable to get the root.

As you can see, when I convert the string into a array of chars, I obtain an incomplete output, with strange chars...somebody can help me?

    char httpJSON[http_response.length()+1];

What is http_response.length() returning? After you've pissed away and fragmented memory all to hell using the String class, do you really have enough memory left to allocate this array?

If you insist on using the String class, you could use it more directly (without copying to another string) with http_response.c_str().

Hi guys,
Many thanks for the advices, and I decided to solve the problem of the memory it this way:

First of all, I have split the code, because I don't love the "monolithic style" xD

This is the loop, where I capture ONLY THE MODEL from the response:

void loop() {  
  if (client.available()){
    model = "";
    while (client.available()){
      char c = client.read();
      //Check if the model begins
      if (c == '{')
        storeJSON = true;  

      if (storeJSON)
        model += c;                        
    }
    parserJSON(model);
    storeJSON=false;
  }
  
  // if twenty seconds have passed since your last connection,
  // then connect again and send data:
  if (millis() - lastConnectionTime > postingInterval) {
    GetData("/GuestCounter/api/event/getDay?DayId=3");
  }
}

This is my HTTP Request:

void GetData(String path) { 
  client.stop();
  client.flush();
  Serial.flush();

  if (client.connect(server, 80)) {
    //Send the HTTP Request
    Serial.println("Fetching Data...");
    Serial.println();
    client.println("GET "+path+" HTTP/1.1");
    client.println("Host: localhost");
    client.println("User-Agent: ArduinoWiFi/1.1");
    client.println("Connection: close");
    client.println(); 
  }
  else{
    Serial.println("connection failed");
  }
  // note the time that the connection was made:
  lastConnectionTime = millis();
}

And this is my function for parsing the string containing the model.

void parserJSON(String model){
  length=model.length()+1;
  char* httpJSON = (char *) calloc(length,sizeof(char));  
  model.toCharArray(httpJSON, length); 

  client.flush();
  Serial.flush();

  Serial.println("MODEL:");
  Serial.print(httpJSON);
  Serial.println();

  aJsonObject* root = aJson.parse(httpJSON);  

  if (root != NULL) {
    aJsonObject* data = aJson.getObjectItem(root, "Data");
    if (data != NULL) {
      aJsonObject* DayId = aJson.getObjectItem(data, "DayId");
      if (DayId != NULL) {
        Serial.println("Day ID:");
        int id=(int)DayId->valuestring;
        Serial.print(id);
        Serial.println();
      }
    }
  }
  else{
    Serial.println("ERROR: Unable to get the root.");
  }
  free(httpJSON);
  free(root);
}

But now I have a different problem...When I run this sketch I obtain this output:

Fetching Data...
MODEL: {"Success":true,"ErrorDescription":null,"ErrorCode":null,"Data":{"EventId":1,"DayId":3,"NumberOfVisitors":0,"Done":false}}
Day ID: 3

Fetching Data...
MODEL: {"Success":true,"ErrorDescription":null,"ErrorCode":null,"Data":{"EventId":1,"DayId":3,"NumberOfVisitors":0,"Done":false}}
Day ID:3

Fetching Data...
MODEL: {"Success":true,"ErrorDescription":null,"ErrorCode":null,"Data":{"EventId":1,"DayId":3,"NumberOfVisitors":0,"Done":false}}
ERROR: Unable to get the root.

Fetching Data...
MODEL: {"Success":true,"ErrorDescription":null,"ErrorCode":null,"Data":{"EventId":1,"DayId":3,"NumberOfVisitors":0,"Done":false}}
ERROR: Unable to get the root.

I can get the root, and then parse the string only twice, then begins to fail parsing...what can I do?
any Ideas?

Thank you boys! :slight_smile:

Well, if you get four captures and then no more, then you code probably does not release the four sockets available after use.