- #include ;
- #include ;
- main(void)
- {
- char *target = "abc";
- char *source = "I love you!";
- strcpy(target, source);
- puts(source);
- puts(target);
- }
复制代码
运行结果:
程序没有考虑目标字符串是否容纳得下源字符串,但编译通过,运行时也复制了想要的目标字符串,但源字符串的内容却被无端修改了,这是因为存储越界引起的吗?
修改代码,将目标字符串改用字符数组表示:
- #include ;
- #include ;
- main(void)
- {
- char target[] = "abc";
- char *source = "I love you!";
- strcpy(target, source);
- puts(source);
- puts(target);
- }
复制代码
运行结果:
- I love you!
- I love you!
- Memory fault(coredump)
复制代码
程序编译通过,运行后,目标字符串得到了想要的复制,源字符串也没有被无端修改,但是coredump了。
在这两个程序中,程序运行的表现显然是不一样的,那么定义字符数组和字符指针有什么区别呢?请大家指点一下!:)
======================================================================
第一个程序中:
char *target = "abc";
char *source = "I love you!";
定义了两个字符指针,但指向的内容却是字符串常量。字符串常量是在编译的时候就分配空间(在DS数据段中),一般为顺序存放,即:
abc\0I love you!\0
对常量的赋值由编译器检查,有的会警告,严格的则报错,禁止对常量赋值。
看一下strcpy(target, source)的后果:
I love you!\0ou!\0
这里原来的abc\0被I lo四个字符覆盖,source指向v,即原来的source变成了ve you!\0ou!\0
打印出来就是ve you!
第二个程序:
char target[] = "abc";
char *source = "I love you!";
target为一个局部数组,其空间在程序运行时分配在栈中,由于是函数中的第一个变量,一般分配在函数返回地址(在函数调用时压入堆栈)的“上面”,所以
strcpy(target, source)
会把返回的地址覆盖掉,这样函数运行正常,但运行结束后要返回调用处时,由于地址被非法修改掉了,造成返回失败,从而coredump
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/16856446/viewspace-682191/
,如需转载,请注明出处,否则将追究法律责任。