0
char str1[]= "To be or not to be";
char str3[]= "To eat or to eat";
char * str2=(char*)malloc(80);
//char str3[40];
str2[0]=NULL;
/* copy to sized buffer (overflow safe): */
strcat(str2, str1);
strcat(str2, str1);
free(str2);str2[0]=NULL;//<<==Marked line
strcat(str2, str3);
strcat(str2, str3);

在下面的代码中,该操作在打印“吃或不吃”2次但如果我删除“str2[0]=NULL;”时运行良好 从标记的行它不起作用并打印“成为或不成为”两次以及“吃或不吃两次”这是为什么?

4

3 回答 3

1

这不是奇怪的行为。Free 完全从内存中删除引用。您实质上是在从标头 string.h中删除具有free(str2);更好使用的变量bzero(str2,80);

于 2013-06-19T14:27:20.343 回答
1

这是未定义的行为

free(str2);

释放指向堆的指针指向的内存并使指针无效。因为使用该指针并访问该内存可以产生任何结果。

话虽如此,看起来在您的实现中内存仍然可以访问,因此后续strcat()调用只需将新字符串附加到原始两个字符串。所以你To be or not to be在缓冲区中有两次,你已经To eat or to eat附加了两次,所以你看到了你在问题中描述的结果。您不应该依赖这种行为 - 在其他情况下,您可能会得到任何其他结果,包括但不限于内存损坏、程序终止等。

于 2013-06-19T14:26:36.603 回答
0

比这更好的是简单地使用 strcpy 和 strcat ,如下所示:

char str1[]= "To be or not to be";
char str3[]= "To eat or to eat";
char * str2=(char*)malloc(80);
//char str3[40];
/* copy to sized buffer (overflow safe): */
strcpy(str2, str1);
strcat(str2, str1);

strcpy(str2, str3);
strcat(str2, str3);

这将是最安全和最简单的方法:)

于 2013-06-19T14:41:33.323 回答