我有一个像这样的代码,这是由K& R书中的练习问题解决的:
#include<stdio.h>
void stringCat(char *s,char *t)
{
while(*s++);
while((*s++ = *t++));
}
void main()
{
char message1[] = "hello whats been up?";
int i;
char message2[] = "this should be added at last";
stringCat(message1,message2);
for(i=0;i<50;i++)
{
printf("%c\n",message1[i]);
}
}
该程序按预期工作,并且我得到如下输出:
hello whats been up?this should be added at last
但是输出后出现错误:
** stack smashing detected : ./a.out terminated ======= Backtrace: ========= */lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)Aborted*
我开始知道为什么会发生here。但我无法弄清楚为什么我的代码会发生这种事情?
我是C的新手,我需要你的帮助。提前谢谢。
答案 0 :(得分:2)
C中的char数组并不完全是字符串。当你这样做
char hello[] = "Hello";
它实际上相当于
char hello[6] = { 'H', 'e', 'l', 'l', 'o', '\0' }
这意味着该数组几乎不足以容纳原始字符串。您在末尾读取或写入的任何数据都将导致未定义的行为,这通常表现为通过自动数组进行写入的堆栈粉碎。
==如何克服:==
有两种选择:
1)确保目标字符串足够长。这样做是打电话者的责任。 strcat()
以这种方式工作。
1b)你可以通过让他们提供目标字符串的大小而不是写出结束来帮助调用者。 strncat()
以这种方式工作。
2)分配足够长的第三个目标字符串。调用者有责任解除分配(释放)此字符串。 @minitech提供了一个这样的例子。 POSIX strdup()
以这种方式工作。
答案 1 :(得分:1)
你有一个缓冲区溢出。 message1
只有足够的空间来存储message1
,而不是自己和message2
。您需要分配一个新的char*
:
char *stringCat(const char *s, const char *t)
{
char *r = malloc(strlen(s) + strlen(t) + 1);
char *p = r;
while(*r++ = *s++);
r--;
while(*r++ = *t++);
*r = '\0';
return p;
}
void main()
{
char message1[] = "hello whats been up?";
char message2[] = "this should be added at last";
char *result = stringCat(message1, message2);
printf("%s", result);
free(result);
}
答案 2 :(得分:1)
这只是因为您的StringCat
函数首先将s
递增到字符串的结尾,然后继续将s
增加到未知的土地,同时也是增加t
。
void stringCat(char *s,char *t)
{
while(*s++);
while((*s++ = *t++));
}
您尝试将t
写入s
以外的内存已分配。
您需要创建一个大小为s + t + 1的新内存空间,并将连接的字符串放在那里。