C 我的字符指针返回奇怪的字符串
在尝试连接两个字符串char数组时,下面的代码通过return返回正确的结果,而不是通过引用传递的参数(即StrAdd函数中的char*dst)返回预期结果 关于后续结果;printf为st打印正确的连接字符串。但是变量s1也应该包含连接字符串。然而,s1打印出一些奇怪的东西 有人能找出它的毛病吗C 我的字符指针返回奇怪的字符串,c,arrays,string,char,C,Arrays,String,Char,在尝试连接两个字符串char数组时,下面的代码通过return返回正确的结果,而不是通过引用传递的参数(即StrAdd函数中的char*dst)返回预期结果 关于后续结果;printf为st打印正确的连接字符串。但是变量s1也应该包含连接字符串。然而,s1打印出一些奇怪的东西 有人能找出它的毛病吗 #include <stdio.h> #include <stdlib.h> #include <string.h> char *StrAdd (char *ds
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *StrAdd (char *dst, const char *src) {
/* add source string "src" at the end of destination string "dst"
i.e. concatenate
*/
size_t lenDst = strlen (dst);
size_t lenSrc = strlen (src);
size_t lenTot = lenDst + lenSrc + 1;
char *sTmp = (char *) malloc (lenTot);
memcpy (&sTmp [0], &dst [0], lenDst);
memcpy (&sTmp [lenDst], &src [0], lenSrc);
sTmp [lenTot - 1] = '\0';
free (dst);
dst = (char *) malloc (lenTot);
memcpy (&dst [0], &sTmp [0], lenTot);
free (sTmp);
return (dst);
}
int main () {
char *s1 = strdup ("Xxxxx");
char *s2 = strdup ("Yyyyy");
char *st = strdup ("Qqqqq");
printf ("s1 before: \"%s\"\n", s1);
printf ("s2 before: \"%s\"\n", s2);
printf ("st before: \"%s\"\n", st);
printf ("\n");
st = StrAdd (s1, s2);
printf ("s1 after : \"%s\"\n", s1); // weird???
printf ("s2 after : \"%s\"\n", s2); // ok
printf ("st after : \"%s\"\n", st); // ok
printf ("\n");
return (0);
}
您将s1传递给函数,然后对其调用free。执行此操作后,指针不再有效,您无法使用它。如果您这样做,就像在printf中那样,您会得到未定义的行为。如果您想创建并返回一个新字符串,只需返回您分配的sTmp,而不释放dst 另一方面,如果确实希望更新传入的目标指针,则需要通过引用传递它,指向指针的指针:
char *StrAdd (char** dstPtr, const char *src) {
char* dst = *dstPtr;
size_t lenDst = strlen (dst);
size_t lenSrc = strlen (src);
size_t lenTot = lenDst + lenSrc + 1;
char *sTmp = (char *) realloc (dst, lenTot); //realloc will also copy the old data for us
strcat(sTmp, src); //same as the second memcpy
*dstPtr = sTmp; //update dest pointer
return sTmp;
}
但你需要这样称呼它:
st = StrAdd (&s1, s2);
在此之后,s1和st指向同一个字符串,请尝试以下操作:
printf ("Addresses after: %p %p\n", (void*)s1, (void*)st);
好的,我在函数中释放dst一次,然后为该变量分配另一个内存空间。第二次分配不是通过标头中的*dst参数返回指针吗?正如在main中打印的那样,它通过return dst返回正确的指针;为什么不通过标题中的*dst?@merkez3110不,您正在释放s1并将新分配的内存分配给st。请参阅的正确实现。请原谅使用了错误的术语。我所说的标题并不是指头文件;我是指函数顶部的char*StrAdd char*dst,const char*src部分。@merkez3110,仅供参考,称为函数definition@merkez3110是的,你仍然需要空间,它只是取代了memcpy。我在第二个例子中使用了strcat示例。也许@2501的解释是正确的,但您的解决方案似乎更好。这样,我想,指向*s1的指针就不会丢失。我添加了一种更新s1的方法。只要确保在释放该字符串时没有其他对该字符串的引用。也就是说,它可能会被realloc释放。realloc可能不会更改指针。不过,您的第一个代码返回新定义的char*,即sTmp似乎更好。这样,如果我想在函数之后使用旧的s1,我会使用sNew=StrAdd s1,s2;如果我允许改变旧的s1,我将使用s1=跨距s1,s2;这方面的问题:s1=跨s1,s2;没有任何东西可以释放旧的s1,并且会导致内存泄漏。char*newS1=strads1,s2;自由1;s1=新闻1;就是这样做的。
printf ("Addresses after: %p %p\n", (void*)s1, (void*)st);