String/char/pointer confusion for sending sms via gsm

Hello,
could you please help me out here? Only the first character 'H' is transmitted via sms, although the corresponding Serial.println(info) shows the whole message? How can I convert the char array 'info' back to a String so that I could forward this String to the SendTextMessage() function? Is there a better way how to do this? Many thanks in advance.
I'm doing float to String to character array conversion in the readWeather() function as it is not possible to return Strings as to my understanding;

Code:

void loop()
{
char *info = readWeather();
       SendTextMessage(info); 
       delay(100);
       Serial.println(info);

}

void SendTextMessage(String message)
{
  cellSerial.print("AT+CMGF=1\r");   
  delay(100);
  cellSerial.println("AT + CMGS = \"+4....\"");
  delay(100);
  cellSerial.println(message);
  delay(100);
  cellSerial.println((char)26);
  delay(100);
  cellSerial.println();
  delay(100);
}

char *readWeather()
{
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  
  char tempF[6]; // character array for temp incl. decimal point & possible minus sign
  char rhPct[6]; // character array for humidity incl. decimal point
  
    
     dtostrf(h, 6, 2, rhPct); //convert float to character array, given the max. length (e.g.6) and digits of decimal points (e.g. 2)
    String rh = String(rhPct);
    
    dtostrf(t, 6, 2, tempF);
    String temp = String(tempF);
        
    String weatherstring= String("Humidity: " + rh + " %\t" + "Temperature: " + temp + " *C\t"); //concatenate strings
    int str_len = weatherstring.length()+1; 
   
    char* chararray = (char*)malloc(str_len); //allocate memory space for char array as otherwise it will be lost once the function exits!
    weatherstring.toCharArray(chararray,str_len); //convert weatherstring (type: String) to Chararray (type: char*)
       
    return chararray;
   }
}

You don't test the result from malloc - you should always check for a NULL result.

The pointer that you assigned a value to goes out of scope when the readWeather() function ends. Returning an out-of-scope pointer is a really bad idea. Using malloc() without a corresponding free() is a really bad idea. Using Strings at all is a really bad idea.

You KNOW how big the array needs to be to hold the weather data. Make a static or global array of that size, and use sprintf() to populate it. Get rid of ALL String objects. Return a pointer to the static array or return nothing if you use a global array.

Thanks for the replies I used sprintf and indeed the code looks much prettier now:

char* readWeather() 
{

  float h = dht.readHumidity();
  float t = dht.readTemperature();
  
  delay(300);
  char temparray[5+1]; 
  char humidityarray[5+1]; 
  static char weatherbuf[40+1]; //static so that value remains inside array if function returns/exits
    
  if (isnan(t) || isnan(h)) // check if returns are valid, if they are NaN (not a number) then something went wrong!
  {
    dtostrf(h, 5, 2, humidityarray); 
    dtostrf(t, 5, 2, temparray);
    sprintf(weatherbuf, "Humidity: %s %% Temperature: %s *C", humidityarray, temparray);   
    return weatherbuf;
   }
}
  if (isnan(t) || isnan(h)) // check if returns are valid, if they are NaN (not a number) then something went wrong!
  {
    dtostrf(h, 5, 2, humidityarray); 
    dtostrf(t, 5, 2, temparray);
    sprintf(weatherbuf, "Humidity: %s %% Temperature: %s *C", humidityarray, temparray);   
    return weatherbuf;
   }

If t is not a number or h is not a number, convert both values to strings, and return the combined result. Otherwise, don't bother returning anything.

Seems a strange definition of "working".