关于strcat()函数

comely312 2003-05-25 08:51:32
在linux系统上,我用c语言编一个小程序:
main()
{
char *p="/mnt/usb";
strcat(p,"kk");
printf("p is %s.\n",p);
}
我想让输出的结果是/mnt/usb/kk,可是运行的结果却是segmatation fault.为什么?请指教。
...全文
744 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
CoolQ 2003-05-27
  • 打赏
  • 举报
回复
>>程序能运行不就可以了吗?
不能这么说啊,这种程序是有潜在错误的阿,要是不小心,会被别人钻空子的阿
comely312 2003-05-27
  • 打赏
  • 举报
回复
好的,谢谢你呀!
CoolQ 2003-05-27
  • 打赏
  • 举报
回复
反正p越大越好,不如设成p[1024]
comely312 2003-05-27
  • 打赏
  • 举报
回复
那我应该怎么做呀,写成char p[30]="/mnt/usb"行吗?
CoolQ 2003-05-27
  • 打赏
  • 举报
回复
结贴吧!!
alangxy 2003-05-26
  • 打赏
  • 举报
回复
出错的原因是你没有为目标串分配空间,另外调用strcat函数时要保证目标串有足够的可以容纳目标串与源串连接起来的整个串的长度,别忘了,最后还有一个'\0'

代码如下:

#include <stdio.h>
#include <string.h>

int main()
{
char p[12] = "/mnt/usb/";
strcat(p,"kk");
printf("p is %s.\n",p);
return 0;
}
comely312 2003-05-26
  • 打赏
  • 举报
回复
那我应该怎么做?把*p改成p[]可以吗?等你不困的时候,请帮帮忙。thanks
comely312 2003-05-26
  • 打赏
  • 举报
回复
程序能运行不就可以了吗?
alangxy 2003-05-26
  • 打赏
  • 举报
回复
两位仁兄讨论的很热闹嘛:)
CoolQ 2003-05-26
  • 打赏
  • 举报
回复
那样是不对的,你没看上边的贴子么?
必须保证p足够大,才能盛下合成的两个字符串阿,否则就会溢出的
所以应该设成至少12字节以上,如果是你的那个例子。
comely312 2003-05-26
  • 打赏
  • 举报
回复
太复杂了,我把*p改成p[]程序就可以了,道理比较难懂。
CoolQ 2003-05-26
  • 打赏
  • 举报
回复
还有一个人给我的回信,我也给你贴一下吧
真搞不懂,指针有这么难学么?把书上的习题做完哪还会问这种问题。

不管是
char *p="Hello";
还是
char p[]="Hello";
都是错误的

这两种情况p都只向一块6字节大小的空间,使用这6字节之后的空间就会引起错误,因为也许它们是某个变量的空间。为了防止对内存地址非法操作,就有了段保护的机制。不可能让你修改内存中任意地址的内容。

比如说这段代码:

#include <stdio.h>

int main()
{
char p[] = "Hello";
p[5] = '!';
p[6] = '\0';
printf("%s\n", p);
}

似乎不会出错,虽然p[6]好像超出了6个字符的限制。
但是如果把p[6]改成p[3000]又如何呢?你可以试一下,100%出错。p[]定义在栈里,运行时根据需要,栈会初始化一个大小,如果试图修改栈以外的地址,就出错。
经常看到有人报错说加一行printf程序就能正常运行,不加这一行就会segmentation falt,其实跟上面的程序一样,程序隐含了致命的问题,只不过因为 printf 改变了堆栈的布局,遮盖了你的程序的漏洞。再试一下在上面程序中char p[] = "Hello"前面加上一! 行char c[3000],那么p[3000]也不会造成错误,因为c[3000]这个变量的定义相当于让栈扩大了。

再看一个直观的例子:
#include <stdio.h>

int main(int argc, char* argv[])
{
char p[] = "Hello";
char i = 1;
p[5] = '!';
for(i = 6; i < 100; i++)
p[i] = 0;
printf("%s, argc=%d\n", p, argc);
}
结果是造成core dump,并且argc的值被改成0
进一步看看
printf("%d, argc=%d\n", *(int*)(p+32), argc);
的输出结果,可以看到p[32]的值和argc是一样的,它们在栈里的地址是一样的。现在你应该相信非法指针操作可能带来的危害了吧?
顺便说一句,问题中没有说是const,所以p是可以操作的。也不要什么都指到c99,那个东西我没看过,我想看过的人也不多。其实弄一本经典的书好好学一下,再多练习练习,我想就差不多了。
/////////////////////////////////////////////////////////////////////
不过我感觉他讲的有对也有错。
主要问题就是p所指的地方到底可不可写,等我再研究研究:)
comely312 2003-05-26
  • 打赏
  • 举报
回复
谢谢,我去linuxforum那里看了,有点明白了。还是很深奥,
CoolQ 2003-05-26
  • 打赏
  • 举报
回复
问题出在你应该是用p[]="/mnt/usb"而不是*p="/mnt/usb",这样p是在栈里
如果如你那样,p是在堆里.具体分析明天再给你搞吧,今天有点困,呵呵
CoolQ 2003-05-26
  • 打赏
  • 举报
回复
我在Linuxforum里提了一些问题,你可以去看看
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=program&Number=414761&page=0&view=&sb=&o=&fpart=1&vc=1

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧