strcpy not acting as expected.

I am writing a class file to create a Http Digest authentication response string. It is doing something weird when I print it out to the serial port, and I don't understand the reason for it.

HttpAuth.h

#ifndef HttpAuth_h
#define HttpAuth_h

// the #include statment and code go here...
#include "Arduino.h"


class HttpAuth
{
  public:
    HttpAuth();
    static void DigestGenerateResponse(char * username,  char * password, char * realm, 
                                      char * method, char * uri, char * nounce, char * qop, 
                                      char * nounceCount, char * clientNounce);

};


#endif

HttpAuth.cpp

#include "HttpAuth.h"

void HttpAuth::DigestGenerateResponse(char * username,  char * password, char * realm, 
                                      char * method, char * uri, char * nounce, char * qop, 
                                      char * nounceCount, char * clientNounce)
{
  char * aOneString;
  char * aTwoString;

  // Build the a1String
  aOneString = (char*) malloc((sizeof(username)+1));
  strcpy(aOneString, username);
  strcat(aOneString, ":");  
  strcat(aOneString, realm);  
  strcat(aOneString, ":");  
  strcat(aOneString, password);

  // Build the a2String
  aTwoString = (char*) malloc((sizeof(method)+1));
  strcpy(aTwoString, method);  
  strcat(aTwoString, ":");  
  strcat(aTwoString, uri);
 
  delay(1000); 
  Serial.println(aOneString);
  delay(1000);
  Serial.println(aTwoString);
}

If I look at the serial monitor I get the result of.

Start
the
GET:/test/testing

when I am really expecting

Start
thenetimp:Bedroom:g@rd3nh0s3
GET:/test/testing

If I remove the code for aTwoString then I get the right return for aOneString so it seems to me like malloc of my 2nd string is interfiering with the 1st string. I don't Understand why it would do that. I wonder if it has to do with me passing in pointers, my C/C++ is not very strong. Can someone please point me in the right direction?

HTTPAuthTest.ino.

#include "HttpAuth.h"

void setup()
{
  Serial.begin(9600);
  delay(1000);
  Serial.println("start");
  
  HttpAuth::DigestGenerateResponse((char*)"thenetimp", (char*)"g@rd3nh0s3", (char*)"Bedroom", 
                                      (char*)"GET", (char*)"/test/testing", (char*)"12345678910", (char*)"auth", (char*)"", (char*)"");  
  
  
}

void loop()
{
}

void print_testing(char * stringy)
{
  char * testing2;
  testing2 = (char*) malloc(11);
  strcpy(testing2, stringy);
  
  Serial.println(testing2);
}
  aOneString = (char*) malloc((sizeof(username)+1));
  strcpy(aOneString, username);
  strcat(aOneString, ":");  
  strcat(aOneString, realm);  
  strcat(aOneString, ":");  
  strcat(aOneString, password);

You allocate exactly enough space to hold username, then you write username, a colon, realm, another colon, and password to that space. How do you expect all that to fit?

PaulS:
You allocate exactly enough space to hold username, then you write username, a colon, realm, another colon, and password to that space. How do you expect all that to fit?

I just figured that out. The website I read that told me about strcpy and strcat did not mention having to allocate enough memory for all of them concatenated together it just allocated memory for the first item in it's example. Guess I won't be using that website anymore... thanks for the response.

You can skip the malloc() calls if you declare your strings as arrays not pointers:

char aOneString[sizeof(username) + sizeof(realm) + sizeof(password) + 3];
char aTwoString[sizeof(method) + sizeof(uri) + 2];

You can also simplify the concatenation code (whether is saves memory I don't know):

  strcpy(aOneString, username);
  strcat(aOneString, ":");  
  strcat(aOneString, realm);  
  strcat(aOneString, ":");  
  strcat(aOneString, password);

would become:

  sprintf(aOneString, "%s:%s:%s",username,realm,password); //where the %s is replaced by the corresponding string