简体   繁体   English

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

[英]Copy c-string char by char to dynamic char*

I have a const char* string, I want to copy that string character by character to dynamic `char*. 我有一个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);

The problem is that previous code just copies each character of constStr to only the first index of the str . 问题在于,先前的代码仅将constStr每个字符constStrstr的第一个索引。 I don't know why? 不知道为什么

As others have pointed out, you are incrementing str pointer in each iteration, so you always end up printing the end of the string. 正如其他人指出的那样,您将在每次迭代中递增str指针,因此您总是最终要打印字符串的末尾。

You can instead iterate over each character without incrementing the pointer. 相反,您可以遍历每个字符而无需增加指针。 The following code worked for me: 以下代码为我工作:

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);

Yes you didn't null terminate the string. 是的,您没有将字符串终止为null。 That was the primary problem. 那是主要问题。 To be more clear, it is not that you didn't nul terminate the string which is the problem but rather your use of them where a pointer to a nul terminated char array is expected is the problem. 更明确地说,不是您不是nul终止了字符串,这是问题所在,而是您在期望使用nul终止char数组指针的地方使用了它们。 But even if you did there was significant amount of problems in the code. 但是,即使您这样做,代码中也存在大量问题。

You allocated the memory and the casted the return value of malloc which is unnecessary. 您分配了内存,并将malloc的返回值malloc为不必要的值。 void* to char* conversion is implicitly done. void*char*转换是隐式完成的。

malloc might not be able to service the request, it might return a null pointer. malloc可能无法处理请求,它可能返回空指针。 It is important to check for this to prevent later attempts to dereference the null pointer. 重要的是要进行检查,以防止以后尝试取消引用空指针。

Then you started copying - you copied everything except the NUL terminating character. 然后开始复制-复制了除NUL终止字符以外的所有内容。 And then you passed it to printf 's %s format specifier which expects a pointer to a null terminated char array. 然后,将其传递给printf%s格式说明符,该说明符需要一个指向以null结尾的char数组的指针。 This is undefined behavior. 这是未定义的行为。

The one position, in the str is uninitialized - beware that accessing uninitialized value may lead to undefined behavior. str的一个位置未初始化-请注意,访问未初始化的值可能会导致未定义的行为。

Also there is another problem, From standard § 7.22.3.3 还有另一个问题,来自标准§7.22.3.3

The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. free函数使ptr指向的空间被释放,即可以用于进一步分配。 If ptr is a null pointer, no action occurs. 如果ptr是空指针,则不执行任何操作。 Otherwise, if the argument does not match a pointer earlier returned by a memory management function , or if the space has been deallocated by a call to free or realloc, the behavior is undefined . 否则,如果参数与内存管理函数先前返回的指针不匹配 ,或者如果通过调用free或realloc释放了空间,则该行为是undefined

Yes so is is the case here? 是的,这里是这样吗? No. when you called free(str) str is not pointing to the dynamically allocated memory returned by the malloc . 否。当您调用free(str) str并不指向malloc返回的动态分配的内存。 This is again undefined behavior. 这也是未定义的行为。

The solution always is to keep a pointer which stores the address of the allocated chunk. 解决方案始终是保留一个指针,该指针存储分配的块的地址。 The other answers already showed them (without repeating them - both of them provides a good solution). 其他答案已经显示了它们(无需重复它们-两者都提供了很好的解决方案)。

You can use strdup or strcpy also - even if you don't need them now - get accustomed with them. 您也可以使用strdupstrcpy即使您现在不需要它们,也要习惯它们。 It helps to know those. 知道这些会有所帮助。 And yes strdup is not part of standard, it is a POSIX standard thing. 是的, strdup不是标准的一部分,它是POSIX标准的东西。

Example: 例:

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);

Here's the "classical" string copy solution: 这是“经典”字符串复制解决方案:

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);

The problem is that previous code just copies each character of constStr to only the first index of the str. 问题在于,先前的代码仅将constStr的每个字符复制到str的第一个索引。 I don't know why? 不知道为什么

  1. Use index variable. 使用索引变量。
  2. Don't forget terminating '\\0' because you have a good chance of segmentation fault. 不要忘记终止“ \\ 0”,因为您很有可能发生分段错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM