我应该如何为 c-string char 数组分配内存?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15179996/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:07:26  来源:igfitidea点击:

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

c++cmemory-managementstring-concatenationcstring

提问by Kurt Von Daimondorf

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

因此,在尝试学习如何在 C++ 中使用 C 字符串时,我遇到了内存分配问题。

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.

这里的想法是创建一个格式为 (s1 + sep + s2) 的新字符串我使用的文本提供了标题,所以我无法更改它,但是我在尝试设置大小时遇到​​了问题字符 str[]。我收到一个错误,说 sLength 不是常数,因此不能用于设置数组的大小。我对 C++ 比较陌生,所以这是一个两部分的问题。

  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 
    char* concatStrings(char* s1, char* s2, char sep){
        int sLength = strlen(s1) + strlen(s2) + 3; 
        //+1 for char sep +2 for 
        char* str = concatStrings("Here is String one", "Here is String two" , c);
        cout<< str;
    
    at end of string char *str = new char[sLength]; strcpy (str, s1); str [sLength(s1)] = sep; strcat (str, s2); return str; }
    at end of string char *str = new char[sLength]; strcpy (str, s1); str [sLength(s1)] = sep; strcat (str, s2); return str; }
  1. 这个策略实际上是为新数组分配内存吗?

  2. 如果无法使用 strlen(char*) 获得常量值,如何正确设置数组大小?

    char* concatStrings(char* s1, char* s2, char sep){
        int s1Length = strlen(s1);
        int sLength = s1Length + strlen(s2) + 2; 
        // +1 for sep and +1 
    char* str = concatStrings(s1, s2, sep);
    
    // Do something
    
    // Free up memory used by str
    delete[] str; 
    
    at end of string char* str = new char[sLength]; strcpy (str, s1); // Use strlen here instead of sizeof() str [s1Length] = sep; str [s1Length + 1] = '
    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 '
    #include <string> // for std::string
    
    std::string str = s1;
    str += sep;
    str += s2;
    
    ' // 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; }
    '; strcat (str, s2); return str; }

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

进行了编辑,所以现在我没有收到编译器错误,但是......

The call to the function is here:

对函数的调用在这里:

##代码##

My output becomes:

我的输出变成:

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

这里是字符串 onec==================22221/21/21/21/2 / (etc.)/ 这里是字符串二

回答by Tuxdude

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.

错误返回本地数组变量的地址str它的作用域concatStrings()在您声明的函数内,一旦控制权从函数返回就无法访问。

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

要在外部访问它,您需要使用new运算符从堆中为字符串动态分配内存。

##代码##

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

并且在程序使用从concatStrings它返回的字符串完成后应该确保通过调用来释放内存delete

##代码##

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

此处必须使用 delete[] 而不是 delete,否则会导致未定义的行为

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

我还编辑了concatStrings()要使用的函数strlen而不是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 str1and sepbefore invoking strcat

更新:感谢您指出我们只需要执行 +2 而不是 +3 并确保在调用之后str1sep之前需要附加 '\0'strcat

回答by Mr.C64

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

您可以动态分配结果字符串内存(在运行时,在堆上),new[]在 C++ 中使用(或者malloc更像 C 的风格):

##代码##

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().

请注意,此内存必须在您的代码中的某处释放,delete[]如果它是用 分配的new[],或者free()如果它是用 分配的malloc()

This is quite complicated.

这是相当复杂的。

You will simplify your code a lot if you use a robust C++ string classlike 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:

如果您使用像 那样健壮的 C++ 字符串类std::string,您将大大简化您的代码,它具有方便的构造函数来分配内存、析构函数来自动释放它,operator+以及operator+=重载来连接字符串。查看如何使用std::string以下方法简化您的代码:

##代码##

(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.)

(请注意,使用原始 C 字符串也会使您的代码更容易受到安全问题的影响,因为您必须非常注意正确调整目标字符串的大小,避免缓冲区溢出等。这是喜欢 RAII 健壮的字符串类(如std::string. )

回答by Code-Apprentice

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

sizeof(s1)返回指针变量的大小,而不是它指向的数组的长度。由于您知道它s1指向 C 字符串,因此您应该改用该strlen()函数。