![](/img/trans.png)
[英]coping contents of the const char* type variable caused unexpected result
[英]How to copy contents of the const char* type variable?
我知道两者之间的区别:
char *a = "string";
char p[] = "string";
从*a
,它的作用如下...
+-----+ +---+---+---+---+---+---+---+
a: | *======> | s | t | r | i | n | g |\0 |
+-----+ +---+---+---+---+---+---+---+
如果我想创建另一个变量说
char *b;
我希望它复制指针 a 指向的所有内容,而不是指向 a 的内容。
+-----+ +---+---+---+---+---+---+---+
a: | *======> | s | t | r | i | n | g |\0 |
+-----+ +---+---+---+---+---+---+---+
b: | *======> | s | t | r | i | n | g |\0 |
+-----+ +---+---+---+---+---+---+---+
这该怎么做 ?
在 C 中,您可以分配一个新的缓冲区 b,然后使用标准库函数将字符串复制到那里,如下所示:
b = malloc((strlen(a) + 1) * sizeof(char));
strcpy(b,a);
注意malloc
的+1
为终止'\\0'
腾出空间。 sizeof(char)
是多余的,但我使用它是为了保持一致性。
在 C++ 中,你应该使用更安全、更优雅的std::string
:
std::string b {a};
在 C++ 中,你可以这样做
const size_t n = strlen(a); // excludes null terminator
char *b = new char[n + 1]{}; // {} zero initializes array
std::copy_n(a, n, b);
但是我建议使用std::string
不是 C 风格的字符串,因为它是
\\0
嵌入的字符串 a
的内容,正如您发布的那样,指向编译器设置的只读内存位置。 如果您想在编译时拥有另一个具有不同值的值,则必须自己定义一个:
char *a = "string";
char *b = "string"; // Nb. This might point to the same location as a
请注意,根据 §2.14.5,这两个指针是否指向同一个内存位置是实现定义的
是否所有字符串文字都是不同的(即存储在非重叠对象中)是由实现定义的。
否则去堆存储的位置,如:
size_t len = strlen(a); // Doesn't include null-terminator character
char *b = new char[len+1];
memcpy(b, a, len); // Assumes plain ASCII string
b[len] = '\0';
无论如何我都会选择std::string
。
您可以使用<string.h>
的非标准(但在许多实现中可用) strdup
函数:
char *b;
strdup(b, a);
...
free(b);
或者您可以使用malloc
和strcpy
保留空间:
char *b;
b = malloc(strlen(a) + 1);
strcpy(b, a);
...
free(b);
的内容a
是你已经标记为*
您图所示。 a
是你的小盒子, a
的内容就是盒子里的东西!
“字符串”不是的内容a
。 它在内存中的其他地方, a
包含该字符串的地址。
复制的内容, a
以b
最终将这样做:
+-----+ +---+---+---+---+---+---+---+
a: | *======> | s | t | r | i | n | g |\0 |
+-----+ / +---+---+---+---+---+---+---+
b: | *====/
+-----+
为了实现您在第二个图中绘制的内容,您需要复制a
指向的所有数据。 这并不简单,因为您如何决定何时停止复制? 没有通用的方法,但是如果您已经预先确定只想复制一个字符串,那么您可以使用一个复制字符串的函数。
常见但非标准的strdup
函数将分配新空间并复制字符串。 否则,您可以分配空间(以任何在 C 中分配空间的常用方式),然后将字符串复制到分配的空间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.