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

后端 未结 3 727
再見小時候
再見小時候 2021-01-05 13:19

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

相关标签:
3条回答
  • 2021-01-05 14:01

    sizeof(s1) returns the size of a pointer variable, not the length of the array which it points to. Since you know that s1 points to a C-string, you should use the strlen() function instead.

    0 讨论(0)
  • 2021-01-05 14:17

    You can allocate the resulting string memory dynamically (at run-time, on the heap), using new[] in C++ (or malloc for a more C-like style):

    char* concatStrings(const char* s1, const char* s2, char sep) // enforced const correctness
    {
        const size_t totalLength = strlen(s1) + strlen(s2) 
                                + 2; // +1 for sep char, +1 for '\0' 
    
        // Dynamically allocate room for the new string (on the heap)
        char* str = new char[totalLength];    
    
        strcpy(str, s1);
        str[strlen(s1)] = sep; // note that you had a typo with sizeof(s1) here
        strcat(str, s2);
        return str;
    }
    

    Note that this memory must be released somewhere in your code, using delete[] if it was allocated with new[], or free() if it was allocated using malloc().

    This is quite complicated.

    You will simplify your code a lot if you use a robust C++ string class like std::string, with its convenient constructors to allocate memory, destructor to automatically free it, and operator+ and operator+= overloads to concatenate strings. See how your code is simplified using std::string:

    #include <string> // for std::string
    
    std::string str = s1;
    str += sep;
    str += s2;
    

    (Note that using raw C strings can also make your code more vulnerable to safety problems, since you must pay lot of attention to proper sizing destination strings, avoid buffer overruns, etc. This is another reason to prefer a RAII robust string class like std::string.)

    0 讨论(0)
  • 2021-01-05 14:19

    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

    0 讨论(0)
提交回复
热议问题