跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 求解答,关于 C 使用 strcpy 问题
未分類
20 1 月 2021

求解答,关于 C 使用 strcpy 问题

求解答,关于 C 使用 strcpy 问题

資深大佬 : NoahNye 3

着实无法理解,为什么已经赋值的 c 和 d 会在 strcpy 之后改变原值(这里故意设置错误下标导致复制越界)

#include <stdio.h> #include <string.h> int main(){          char a[6]={"hello"},b[7]={"world1"};         // a[]="hello";         // b[]="world";          int c,d;         int *c_,*d_;          c=(int)sizeof(a)/sizeof(*a);         d=(int)sizeof(b)/sizeof(*b);         // c_=&c;         // d_=&d;          // printf("c_=%ptd_=%pn",c_,d_);         // printf("c=%ptd=%pn",&c,&d);         printf("c=%d,d=%dn",c,d);          strcpy(a,b);          printf("%s-%sn",a,b);         printf("c=%d,d=%d",c,d);    } 

运行结果: !run1 [[email protected] Ctest]# ./test
c=6,d=7
world1-world1
c=6,d=0
求解答,关于 C 使用 strcpy 问题

并且,在用新的指针赋值之后,这个 c 和 d 又不会因为 strcpy 而改变原值了。

#include <stdio.h> #include <string.h> int main(){          char a[6]={"hello"},b[7]={"world1"};         // a[]="hello";         // b[]="world";          int c,d;         int *c_,*d_;          c=(int)sizeof(a)/sizeof(*a);         d=(int)sizeof(b)/sizeof(*b);         c_=&c;         d_=&d;          // printf("c_=%ptd_=%pn",c_,d_);         // printf("c=%ptd=%pn",&c,&d);         printf("c=%d,d=%dn",c,d);          strcpy(a,b);          printf("%s-%sn",a,b);         printf("c=%d,d=%d",c,d);    } 

运行结果:
[[email protected] Ctest]# ./test
c=6,d=7
world1-world1
c=6,d=7
求解答,关于 C 使用 strcpy 问题

测试了 gcc 和 clang,只有 gcc 出现这个问题。

大佬有話說 (14)

  • 資深大佬 : hello2060

    已经忘了 C 了,但是既然 stripy 越界了,变量值改变也是有可能的啊,你看看数组 a 和 d 的地址,看看 d 是不是跟在 a 数组元素后面

  • 資深大佬 : shuax

    你不懂什么叫越界吗

  • 資深大佬 : hello2060

    最简单的,IDE 里单步 debug 看 memory 变化

  • 資深大佬 : hello2060

    最后你定义了 c_ d_那可能就改变了栈内各个变量地址的关系,本身正常的程序就不预设栈内变量地址之间的关系。一旦越界了,啥都有可能发生。

    不过最简单的还是 debug 一下

  • 資深大佬 : hello2060

    你说你无法理解,这个不需要理解啊,因为这个 code 出错了,所以啥错误都是有可能的。

  • 主 資深大佬 : NoahNye

    @hello2060 谢谢回复,之前有发过在 stackoverflow,好像也差不多得到这种回答,大概是错误的代码导致不可预期的行为,但我还是觉得这个赋值的这两个变量不应该因为 strcpy 而改变,因为它们并没有在 strcpy 之后被重新赋值。既然是程序错误,我也不在这个错误代码里钻牛角尖了。最后再次感谢您的回复。

  • 資深大佬 : LANB0

    如一所说,你 strcpy 越界了。越界的字节覆盖了变量 d 低字节的内存,后一种写法,d_的值也是有误的。
    Linux 下局部变量内存地址分布顺序:
    按字节大小,大的先入栈;
    字节大小相同的,后定义的先入栈;

    按定义顺序,依次入栈的是 c,d,a,b ; intel 小端,d 的低字节和 a 的末尾是连着的;进而溢出的’’把 d 的低字节覆盖了

  • 資深大佬 : hello2060

    strcpy(a, b) 的时候 a + 6 和 a + 7 那个位置的值都被错误的覆盖了(我已经忘了最后的 是怎么处理的了,反正至少有一个 byte 被 strcpy 这个动作错误的改写了,

    d 的内存地址可能刚好包括这个 byte, ‘这个赋值的这两个变量不应该因为 strcpy 而改变,因为它们并没有在 strcpy 之后被重新赋值’ — 变量 d 并不是只有被重新赋值了才会有新值,任何操作他内存地址的操作都有可能改变他的值啊

    比如说你定义

    char a, char b, 假设他们在内存里是 [a,b]
    你再定义 int* p = &a, (我不确定这个是否是正确的语法)
    *p = 0, 这里对 p 的内存改写,因为 p 指向 4 个 byte 的 int, 从 a 地址开始的 4 个 byte 都变成 0 了,b 也变 0 了

  • 資深大佬 : nightwitch

    继续往下学吧,如果你只停留在 C 语法上的话,大家跟你解释你也不大听得懂。
    这个问题你学到 C 语言的基本类型在机器上的内存排布就自然明白了

  • 資深大佬 : changcui

    和 strcpy 无关吧,sizeof 是编译的时候就计算好的

  • 資深大佬 : ipwx

    怎么又讨论起未定义行为了?讨论这种的行为没有意义,因为 -O3 可以把指令都乱序,内存读取跳过(用寄存器),诸如此类的。。。

  • 資深大佬 : huangmingyou

    gdb 解君愁

  • 資深大佬 : ghostcir

    因为 a 内存越界了,结尾的 填到了 d 的内存

  • 資深大佬 : aneostart173

    第一个 c_和 d_都没用,编译器给优化掉了, 第二个 c_和 d_都用上了,栈布局就变了。越界了什么事都会发生,讨论这个没任何意义。

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具