How should I allocate memory for c-string char array?

Kurt Von Daimondorf picture Kurt Von Daimondorf · Mar 2, 2013 · Viewed 40.8k times · Source

So in attempting to learn how to use C-Strings in C++, I'm running into issues with memory allocation.

The idea here is that a new string is created of the format (s1 + sep + s2) The text I'm using provided the header, so I can't change that, but I'm running into issues trying to set the size of char str[]. I am getting an error saying that sLength is not constant, and therefore cannot be used to set the size of an array. I'm relatively new to C++ so this is a two part question.

  1. Is this strategy actually allocating memory for the new array?

  2. How do I set the array size correctly if I can't get a constant value using strlen(char*)?

    char* concatStrings(char* s1, char* s2, char sep){
        int sLength = strlen(s1) + strlen(s2) + 3; 
        //+1 for char sep +2 for \0 at end of string
        char *str = new char[sLength];
        strcpy (str, s1);
        str [sLength(s1)] = sep;
        strcat (str, s2);
        return str;
    }
    

Edits made, so now I'm getting no compiler errors but...

The call to the function is here:

    char* str = concatStrings("Here is String one", "Here is String two" , c);
    cout<< str;

My output becomes:

Here is String onec==================22221/21/21/21/2 /(etc.)/ Here is String two

Answer

Tuxdude picture Tuxdude · Mar 2, 2013

Error is returning address of local array variable str. Its scope is within function concatStrings() where you declared, and can't be accessed once control returns from the function.

To access it outside, you need to dynamically allocate memory for the string from the heap using the new operator.

char* concatStrings(char* s1, char* s2, char sep){
    int s1Length = strlen(s1);
    int sLength = s1Length + strlen(s2) + 2; 
    // +1 for sep and +1 \0 at end of string
    char* str = new char[sLength];
    strcpy (str, s1);
    // Use strlen here instead of sizeof()
    str [s1Length] = sep;
    str [s1Length + 1] = '\0';
    strcat (str, s2);
    return str;
}

And after the program is done using the string returned from concatStrings it should ensure to free up the memory by invoking delete

char* str = concatStrings(s1, s2, sep);

// Do something

// Free up memory used by str
delete[] str; 

Must use delete[] here instead of delete, or it results in undefined behaviour

I've also edited the concatStrings() function to use strlen instead of sizeof

UPDATE: Thanks for pointing out that we only need to do +2 and not +3 and for making sure a '\0' needs to be appended after str1 and sep before invoking strcat