将 c 字符串字符复制到动态字符*



我有一个const char*字符串,我想逐个字符将该字符串复制到动态"char*"。

const char *constStr = "Hello world";
char *str = (char*) malloc(strlen(constStr)+1);
while(*constStr){
*str = *constStr;
constStr++;
str++;
}
printf("%s", str);
free(str);

问题是以前的代码只是将constStr的每个字符复制到str的第一个索引。我不知道为什么?

正如其他人指出的那样,您在每次迭代中都会递增指针str因此您最终总是打印字符串的末尾。

您可以改为循环访问每个字符,而不增加指针。以下代码对我有用:

const char *constStr = "Hello world";
int len = strlen(constStr);
char *str = (char *) malloc(len + 1);
int i;
for (i = 0; i <= len; ++i) {
str[i] = constStr[i];
}
printf("%s", str);
free(str);

是的,您没有将字符串终止为空。这是主要问题。更清楚的是,并不是您没有 NUL 终止字符串,这是问题所在,而是您在预期指向 NUL 终止的 char 数组的指针的情况下使用它们。但即使你这样做了,代码中也存在大量问题。

您分配了内存并强制转换了malloc的返回值,这是不必要的。void*char*转换是隐式完成的。

Malloc 可能无法为请求提供服务,它可能会返回空指针。重要的是 检查这一点以防止以后尝试取消引用空指针。

然后你开始复制 - 你复制了除 NUL 终止字符之外的所有内容。然后你把它传递给printf%s格式说明符,它需要一个指向以空结尾的字符数组的指针。这是未定义的行为。

str中的一个位置是未初始化的 - 请注意,访问未初始化的值可能会导致未定义的行为。

还有另一个问题,来自标准§7.22.3.3

free函数使ptr指向的空间被解除分配,即可用于进一步分配。如果ptr为空指针,则不会执行任何操作。否则,如果参数与内存管理函数之前返回的指针不匹配,或者空间已通过调用 free 或 realloc 解除分配,则行为是未定义的

是的,这里的情况是这样吗?不。调用时free(str)str不指向malloc返回的动态分配内存。这又是未定义的行为。

解决方案始终是保留一个指针,用于存储已分配块的地址。其他答案已经显示了它们(不重复它们 - 它们都提供了一个很好的解决方案)。

您也可以使用strdupstrcpy- 即使您现在不需要它们 - 习惯它们。了解这些会有所帮助。是的,strdup不是标准的一部分,而是POSIX标准的东西。

例:

const char *constStr = "Hello world";
char *str = malloc(strlen(constStr)+1);
if( !str ){
perror("malloc");
exit(EXIT_FAILURE);
}
char *sstr = str;
while(*constStr){
*str = *constStr;
constStr++;
str++;
}
*str = 0;
printf("%s", sstr);
free(sstr);

下面是"经典"字符串复制解决方案:

const char *constStr = "Hello world";
char *str = malloc(strlen(constStr) + 1), *p = str;
/* Do not forget to check if str!=NULL !*/
while((*p++ = *constStr++));
puts(str);

问题是以前的代码只是复制了 constStr 仅对 str 的第一个索引。我不知道为什么?

  1. 使用索引变量。
  2. 不要忘记终止"\0",因为您很有可能出现分段错误。

最新更新