C_and_CPP 板


LINE

※ 引述《Keitaro (動き出す時間...)》之銘言: : 開發平台(Platform): (Ex: Win10, Linux, ...) : Ubuntu 18.04 LTS : 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出) : gcc : 程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔) : https://ideone.com/jugcYC : 重新上傳完整原始碼 後面恕刪, 因為看起來不像 C++ 所以路過分享一下拙見. C++ 物件不僅僅是一塊記憶體, 因為生命週期中會有建構子/解構子參與, 簡單 說就是至少會比 C 語言多兩次函式呼叫. 所以撰寫的時候不會輕易地創造物件 , 更不會創完而不用它. array new/delete 這種昂貴的操作其實是蠻罕見的. 你的程式碼主要存在兩個問題: 1. ParseCmd() 的實作沒有彈性, 且效率不高 2. 準備 execve() 引數時做了許多不必要的操作 一般為了減少對 STL container 的依賴, 函式介面會傾向於接受迭代器而不是 特定容器型別物件, 而且除非你很確定要用 std::char_traits<CharT>::eq() 來比較字元是否相等, 不然我們在搜尋的時候傾向於呼叫 STL algorithm 而非 std::basic_string 這種內嵌比較邏輯的型別, 所以通常介面會這樣設計: template <typename ForwardIterator, typename ForwardSentinel, typename OutputIterator> void ParseCmd(ForwardIterator first, ForwardSentinel last, OutputIterator output) { while (first != last) { // call std::find() here // other code goes here (*output++) = std::string(first, last); } } #include <iterator> const std::string str = "-vsync 0 -i file.cfg Compare.yuv"; std::vector<std::string> vCmdSet; ParseCmd(begin(str), end(str), std::back_inserter(vCmdSet)); std::basic_string 只作為字元的載體, 而不是兼做比較的角色. 再來是準備 execve() 引數的邏輯, 如果非得用 array new/delete 來管理物 件, 那前面呼叫 ParseCmd() 創建一堆 std::string 物件有什麼用呢? 有沒 有辦法重複使用這些物件的內容呢? 實際上你可以呼叫 std::string::data() 成員函式來達成這件事情, 然後把拿到的指標存進另一個 std::vector 內: #include <algorithm> #include <iterator> std::vector<char*> ppCmdArg; std::transform(begin(vCmdSet), end(vCmdSet), std::back_inserter(ppCmdArg), [](std::string& s) { return data(s); }); ppCmdArg.push_back(nullptr); execve(..., data(ppCmdArg), ...); 這裡用到的概念主要有兩個: 1) std::vector 的 data() 成員函式會回傳第 0 個元素的位址, 而且每個成員的位址保證是連續的, 所以回傳的東西和你用 array new 創建出來的 array of pointers 是相同的; 2) 再者 std::string 的 data() 成員函式會回傳第 0 個字元的位址, 每個字元的位址也是連續的, 而且回傳的記憶體和 c_str() 相同 (只差在 constness), 包含結束字元. 下次撰碼的時候可以試著寫出無 new/delete 的程式碼, 因為偏底層的函式呼 叫次數愈多, 發生錯誤的機會也跟著變多. -- [P1389R1] Standing Document for SG20: Guidelines for Teaching C++ to Beginners https://wg21.link/p1389r1 SG20 Education and Recommended Videos for Teaching C++ https://www.cjdb.com.au/sg20-and-videos --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.193.76.216 (臺灣)
※ 文章網址: https://webptt.com/m.aspx?n=bbs/C_and_CPP/M.1605102909.A.FC2.html
1F:→ Lipraxde: new 的問題是會產生 raw pointer,要主動用 delete 釋 11/11 22:28
2F:→ Lipraxde: 放資源。至於昂貴嗎...難道 vector、string 就不做 hea 11/11 22:28
3F:→ Lipraxde: p allocation 了? 11/11 22:28
STL container 預設會用 std::allocator<T> 來做配置, 以物件的生命週期來 看, 呼叫的介面先後順序如下: 1. allocate() 2. construct() 3. destroy() 4. deallocate() 1 ~ 2 的使用效果和 operator new + placement new 相同, 並非使用 array new, 差別在於元素是需要用到的時候才建構, 而非一次全部建構好, 這也是為 什麼如 std::vector 會有 capacity() 及 size() 兩種不同用途的成員函式. 說 new 會產生 raw pointer 那不會是什麼太大問題, 因為使用者可以選擇重 載 new/delete, 只要在重載版本裡做好物件管理即可.
4F:→ CoNsTaR: 還是看使用情景吧,server 可能就會想要一次全部建構好 11/11 23:58
5F:推 Keitaro: 謝謝板上各位先進的指導 11/12 03:48
6F:→ Keitaro: 雖然有很多東西不太了解 我在努力查資料學習 11/12 03:49
7F:→ Keitaro: 讓各位花這麼多時間指導小弟 真的非常感謝 11/12 03:50
8F:推 ucrxzero: 是說內文說用s.data()可是代碼用data(s)是我看錯嗎? 11/12 10:10
是的, 你沒看錯
9F:→ Lipraxde: 我主要是不明白為什麼你文內會寫說 new/delete 昂貴( 11/12 22:49
10F:→ Lipraxde: 還是 array 這個字眼在這邊很重要?)。 11/12 22:49
你知道 operator new 以及 operator new[] (俗稱 array new) 的差異嗎? 遇到沒有 default constructor 的型別初始化會怎麼進行?
11F:→ Lipraxde: 我怎麼覺得是用法的問題,而不是它本身昂貴? 11/13 01:56
昂貴的原因在於物件的建構方式. 如同陣列般, 元素的建構是彼此相依的, 除了獲取記憶體的時間成本; 也額外 付出了第 1 個元素開始建構到第 n - 1 個元素結束建構的時間 (n 為陣列大 小), 我們才能開始存取第 0 個元素. 為了使用 operator new[] 來建構大量物件, 使用者還必須提供成本較低的 default ctor, 讓型別支援 two-phase initialization, 也提高程式碼複雜度 所以物件分開建構與否直接影響程式的執行效率, 從 C++17 開始新增多種記憶 體管理介面如 std::byte, std::uninitialized_*() 系列函式, 即是為了完善 這部分的開發.
12F:推 Hurricaneger: 看不懂就推 11/13 10:40
13F:→ Lipraxde: 喔~所以說,就是這些多呼叫的 default constructor 造 11/13 11:30
14F:→ Lipraxde: 成它比較貴,感到豁然開朗!我以前基本上都當 default 11/13 11:30
15F:→ Lipraxde: constructor 沒什麼成本 Orz 11/13 11:30
如果是 trival default ctor 就不會有什麼成本. 但從 C++11 開始有執行緒的觀念; C++17 開始有 executor 平行處理的觀念, 在使用 operator new[] 這類操作以前都要思考是否有必要排隊循序執行. ※ 編輯: poyenc (61.216.75.43 臺灣), 11/13/2020 12:04:52
16F:推 F04E: 這種優文竟然只有三推 11/13 13:03
17F:推 Lipraxde: 謝謝大大的指導 11/13 22:23







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:BuyTogether站內搜尋

TOP