我应该如何为c-string char数组分配内存?
因此,在尝试学习如何在C ++中使用C-Strings时,我遇到了内存分配问题。
这里的想法是创建一个新的字符串格式(s1 + sep + s2)我正在使用的文本提供了标题,所以我不能改变它,但我遇到了试图设置大小的问题char str []。 我收到一个错误,说sLength不是常量,因此不能用于设置数组的大小。 我对C ++比较陌生,所以这是一个两部分问题。
-
这个策略实际上是为新arrays分配内存吗?
-
如果使用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; }
编辑,所以现在我没有编译错误,但…
对函数的调用如下:
char* str = concatStrings("Here is String one", "Here is String two" , c); cout<< str;
我的输出成为:
这是字符串onec ================== 22221/21/21/21/2 / (等) /这里是字符串二
错误是返回本地数组变量str
地址 。 它的作用域在你声明的函数concatStrings()
中,并且一旦控制从函数返回就无法访问。
要在外部访问它,您需要使用new
运算符为堆中的字符串动态分配内存。
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; }
在使用从concatStrings
返回的字符串完成程序之后,它应该确保通过调用delete
来释放内存
char* str = concatStrings(s1, s2, sep); // Do something // Free up memory used by str delete str;
我还编辑了concatStrings()
函数来使用strlen
而不是sizeof
更新:感谢指出我们只需要做+2而不是+3并确保在调用strcat
之前需要在str1
和sep
之后追加’\ 0′
你可以动态地 (在运行时,在堆上)分配结果字符串内存,在C ++中使用new[]
(或者使用malloc
来获得更像C的样式):
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; }
请注意,必须在代码中的某处释放此内存,如果使用delete[]
分配,则使用delete[]
如果使用malloc()
分配,则使用free()
malloc()
。
这很复杂。
如果您使用强大的C ++字符串类(如std::string
,并使用方便的构造函数来分配内存,析构函数自动释放它,以及operator+
和operator+=
重载来连接字符串,那么您将大大简化代码。 使用std::string
查看代码的简化方式:
#include // for std::string std::string str = s1; str += sep; str += s2;
(请注意,使用原始C字符串也会使您的代码更容易受到安全问题的影响,因为您必须非常注意正确的大小调整目标字符串,避免缓冲区溢出等。这是另一个选择RAII健壮字符串类(如std::string
)的另一个原因std::string
。)
sizeof(s1)
返回指针变量的大小, 而不是它指向的数组的长度。 既然你知道s1
指向一个C字符串,你应该使用strlen()
函数。