[問題]實作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