[问题]实作strcpy产生bus error的问题

楼主: ericerix (Ponwar)   2021-07-24 01:05:15
开发平台(Platform): (Ex: Win10, Linux, ...)
macOS
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
gcc
额外使用到的函数库(Library Used): (Ex: OpenGL, ...)

问题(Question):
bus error
喂入的资料(Input):

预期的正确结果(Expected Output):
正确strcpy
错误结果(Wrong Output):
bus error
程式码(Code):(请善用置底文网页, 记得排版,禁止使用图档)
可正确完成:
程式码a.
https://pastebin.com/dic0xAgn
我想问的错误程式码:
程式码b.
https://pastebin.com/6S1VE5nF
另外一种程式码:
程式码c.
https://pastebin.com/w8J8cxBv
补充说明(Supplement):
不知道是不是我观念问题错很大,连续两篇有关string的位址问题XD
先说,这三个程式码只差在第13行
a.是我后来突发奇想这样改,结果对了:
strcopy((char *)&a, (char *)&b);
b.我一开始是这样写的:
strcopy(a,b);
c.是我用线上编译器做的,b喂进去会错,才这样在线上编译器改:
strcopy(&a,&b);
我一开始在本机的compiler是写b的程式码,
一直出现bus error,真的是搞不懂,
因为我有实作另一个strlen,就是用b的方法传进去,
然后内部s++;count++;这样
但在copy会错,
后来在线上编译器实作b的方法,也会错,
改成c后,就可以了
但很不合理啊,c这样传入的应该是char **,居然会对?
后来在本机的compiler写a的做法,
我自己觉得很奇怪,为什么这样可以,但b不行?
求大大们开示
作者: loveme00835 (发箍)   2021-07-24 01:13:00
你知道 char *a = "abcd"; 和 char a[] = "abcd"; 之间的差别吗?
作者: galic (嘎利)   2021-07-24 01:15:00
这个真的神 误打误撞 他的strcopy结果等同a = b;等于是把a指标改指向跟b指标指向的位址相同...老板应该帮你加薪 不但完成了需求 而且效能更佳
作者: loveme00835 (发箍)   2021-07-24 01:25:00
那你知道两者指向的空间有什么差异吗?那个叫做 string literal 不是 string, 当编译器看到string literal 时会偷偷建立阵列来储存对应的字符,这个阵列的生命周期很长, 而且你不能改变它的内容,所以虽然可以用 char* 指向这个阵列去读取内容, 不用强制加 const 是因为从 ANSI C 开始就很多这种程式码, 所以一直沿用至今. 如果只是单纯参考 string literal 的内存, 最好加上 const; 如果你是要储存字串处里的结果, 就得另外定义阵列. char a[] = "abcd"; 这种定义方式就是另外创一个阵列, 然后它会有和 stringliteral "abcd" 相同的内容. 所谓的字串是指以 '\0'结尾的资料流, 而必须有连续的内存区块才能装这个资料流, 那最常见的就是用阵列或是动态内存配置,利用 string literal 建立的阵列因为唯读的特性, 通常只会用在如 printf() 的格式字串上因为有两个 string literal "1234" 还有 "3456", 你没有改变阵列的内容, 你只是将原本指向 "1234" 阵列的 d 改指向 "3456" 而已, 不信的话你用 %p 印出 d的值就知道, 所谓的"修改字串值"意思是在同一块内存上面修改字符内容.C 语言字串不是变量, 字串是资料流用 char* 定义的变量不是字串, 只是指向资料流的指标简单来说就是阵列复制而已, 只是阵列的元素从 int 换成 char, 没什么特别的

Links booklink

Contact Us: admin [ a t ] ucptt.com