我有一个动态分配的char
数组,我想将两个字符串合并到其中,所以我尝试了以下内容:
char *strcpy2 (char *str1, char *str2)
{
int total = strlen (str1) + strlen (str2) + 1;
char *nstr = malloc (sizeof (char) * total);
while (*str1 != '\0') *nstr++ = *str1++;
while (*str2 != '\0') *nstr++ = *str2++;
*nstr = '\0';
printf ("size: %d\n", strlen (nstr));
return &(nstr[0]);
}
int main (void)
{
char *concat = strcpy2 ("Hello, ", "World.");
puts (concat);
free (concat);
return 0;
}
当我运行它时,打印的nstr
的大小为0,然后是Segmentation fault (core dumped)
。
然而,当我这样做时:
char *strcpy2 (char *str1, char *str2)
{
int total = strlen (str1) + strlen (str2) + 1;
char *nstr = malloc (sizeof (char) * total);
char *p = nstr;
while (*str1 != '\0') *p++ = *str1++;
while (*str2 != '\0') *p++ = *str2++;
*p = 0;
printf ("size: %d\n", strlen (nstr));
return nstr;
}
工作正常并打印了nstr
的正确长度。我很困惑,是什么导致了撞车?
答案 0 :(得分:4)
您需要返回nstr
最初返回的malloc()
的值。
您的第一个代码块递增nstr
,直到它指向已分配内存的末尾。然后代码尝试使用并释放该地址,该地址不属于您的程序。
您需要保存字符串的起始地址,以便将其返回。
答案 1 :(得分:1)
在第一种情况下,您不断增加nstr
,最后使用
printf ("size: %d\n", strlen (nstr));
其中nstr
指向所有增量(包含null
)后的最终位置。结果为0长度。然后,将递增的指针返回给调用者并尝试free()
它。结果在Undefined Behavior。
OTOH,在第二种情况下,你有一个指向主要分配的内存的指针,你通过它来计算字符串长度,返回正确的值,之后,free()
- ing也是正确的,所以它起作用预期
答案 2 :(得分:0)
在第一个函数中,您返回错误的指针。它指向字符串的null终止符,因此长度为零。当您尝试free()
它时,它不是您从malloc()
获得的指针。未定义的行为结果。
答案 3 :(得分:0)
复制两个字符串时,您正在递增The sample code can be seen in this fiddle:
指针,这是您用来表示字符串本身的指针。只需将其复制到另一个变量中,并在引用字符串时使用它:
nstr
您可以在此处看到它:https://ideone.com/ncpVMU
我也冒昧地修复了你的愚蠢归还声明:
char *strcpy2 (char *str1, char *str2)
{
int total = strlen (str1) + strlen (str2) + 1;
char *nstr = malloc (sizeof (char) * total);
char *str = nstr; // the string
while (*str1 != '\0') *nstr++ = *str1++;
while (*str2 != '\0') *nstr++ = *str2++;
*nstr = '\0';
printf ("size: %d\n", strlen (str)); // used here
return str; // and here
}