鱼C论坛

 找回密码
 立即注册
查看: 1785|回复: 6

P19:字符串处理函数

[复制链接]
发表于 2021-1-20 22:08:46 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
为什么我能成功复制过去?
上面的是小甲鱼的,下面的是我的
图片1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-1-20 22:12:47 | 显示全部楼层
能成功复制,也是问题?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-20 22:41:19 | 显示全部楼层
风过无痕1989 发表于 2021-1-20 22:12
能成功复制,也是问题?

小甲鱼在视频里说会出错,所以有了 strncpy
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-20 23:07:17 | 显示全部楼层
会有那么一天么 发表于 2021-1-20 22:41
小甲鱼在视频里说会出错,所以有了 strncpy

这个视频我看得时间已经比较久远了,记不清他在视频里是怎么说的了。
从你的程序来看,你用的是不定长数组,复制过去肯定是没有问题的,若你用有限长数组,那就不一定了。
你也别对这个问题太认真了,知道是怎么回事,知道怎么用 strcpy() 函数就可以了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-21 00:29:35 | 显示全部楼层
本帖最后由 jackz007 于 2021-1-21 00:54 编辑

        试试这个代码就可以找到答案了
#include <stdio.h>
#include <string.h>

int main(void)
{
        char A[] = "aaaaaaaaaaaa"  ;
        char B[] = "bbbbbbb"       ;
        char C[] = "ccccccc"       ;
        char D[] = "ddddddd"       ;
        printf("A = %s\n" , A)     ;
        printf("B = %s\n" , B)     ;
        printf("C = %s\n" , C)     ;
        printf("D = %s\n" , D)     ;
        strcpy(C , A)              ;
        printf("after copy\n")     ;
        printf("A = %s\n" , A)     ;
        printf("B = %s\n" , B)     ;
        printf("C = %s\n" , C)     ;
        printf("D = %s\n" , D)     ;
}
        编译运行实况
D:\00.Excise\C>g++ -o x x.c

D:\00.Excise\C>x
A = aaaaaaaaaaaa
B = bbbbbbbb             <--- 注意这里
C = cccccccc
D = dddddddd
after copy
A = aaaaaaaaaaaa
B = aaa                  <--- 注意这里
C = aaaaaaaaaaaa
D = dddddddd

D:\00.Excise\C>
        为了说明问题,我把代码稍微改了一下。
        A 的长度是 12 个字符,加上字符串结束标志字符 '\0' 一共占用了内存 13 个字节,B、C、D 长度都是 8 个字符,各占用 9 个字节内存,现在,把字符串 A 复制到 C 中,通过显示 C 我们可以看到,复制确实是成功的,可是,C 明明只有 8 个字符空间,却容纳了整整12个字符,这是怎么做到的?究竟是怎么回事?答案是字符串复制时,越界侵占了相邻变量的内存空间。这一点,从显示出的字符串 B 中就可以找到答案。在字符串 C 能 "正常" 被显示的同时,字符串 B 已经从原来的 8 个字符 'b' ,令人惊讶地变成了 3 个字符 'a', 仔细想一下,C 可以容纳从 A 复制过来字符串中的前 9 个字符,多出来的后 3 个字符显然是侵占了属于字符串 B 的内存空间,侵占了多少呢?答案是 3 个 'a' 外加 1 个 '\0',一共 4 个字节,这就是真相,这也是 B 显示 3 个字符 'a' 的真实原因。
        在本例中,被侵占内存空间的变量是字符串,对程序运行逻辑的影响不是太大,如果是其他类型的变量,有可能对程序运行逻辑产生致命的影响,所以,任何时候都不能越界使用任何变量!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-1-21 23:03:20 | 显示全部楼层
jackz007 发表于 2021-1-21 00:29
试试这个代码就可以找到答案了

        编译运行实况

我编译后B还是bbbbbbbb
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-1-21 23:31:40 | 显示全部楼层
本帖最后由 jackz007 于 2021-1-22 00:10 编辑


        我是在 gcc 下看到的这个结果。
        我又用 VC 编译了一下,运行结果与你一样,很是奇怪,于是,我用 OD 跟踪了编译好的可执行程序,发现这几个字符串在内存中的布局与我们的想象完全不一致。
0012FF14  64 64 64 64 64 64 64 00 62 62 62 62 62 62 62 00  ddddddd.bbbbbbb.
0012FF24  61 61 61 61 61 61 61 61 61 61 61 61 00 51 40 00  aaaaaaaaaaaa.Q@.
0012FF34  63 63 63 63 63 63 63 00                          ccccccc
        字符串在 内存中的分布顺序既不是A、B、C、D,也不是 D、C、B、A,而是 D、B、A、C,在这种情况下,把 A 复制到 C 当中,通过显示 A、B、C、D 还真看不出问题。
        针对这一情况,这一句
       strcpy(C , A)              ;
        得改成
       strcpy(D , A)              ;
        应该可以看到效果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-15 08:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表