[問題] 請問char**array的問題

作者: Keitaro (動き出す時間...)   2020-11-10 19:53:34
開發平台(Platform): (Ex: Win10, Linux, ...)
Ubuntu 18.04 LTS
編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
gcc
程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔)
https://ideone.com/jugcYC
重新上傳完整原始碼
補充說明(Supplement):
程式碼如以上連結
想請教版上各位先進 我的程式碼這一段是否出了什麼問題
這段code作用是這樣的
1. 我要寫一個自己用的CreateProcess() 在linux底下去call process起來做事
2. 中間是fork...exec 因為前面印出來就發現有問題了
我覺得應該是跟fork以後開始沒關係
3. 傳進來的參數
p_sAppName: process name
p_sCmdArg: parameter, 以空白切割, 所以我會去呼叫一個自己寫的ParserCmd()
去把傳進來的參數去parser成一個vector<string> 把所有參數放裡面
ParserCmd()的結果我確定是對的所以忽略不貼
p_sEnvArg: 環境變數的參數, 作法如同上面的p_sCmdArg
p_nRetVal: 在fork()...exec()這段拿來回傳呼叫process的成功或失敗
假設我今天call這個function的呼叫方式是這樣
MyCreateProcess("ffmpeg", "-vsync 0 -i file.cfg Compare.yuv");
p_sEnvArg/p_nRetVal有預設值NULL
我預計進入function後
1. 傳進來的p_sCmdArg, 會被ParserCmd()拆解然後存每一個cmd在vector裡面
2. 由於execve需要傳參數/環境變數型態為char**, 所以我先
char **ppCmdArg = new char*[vCmdSet.size() + 1];
然後在迴圈中, 針對於每一個ppCmdArg[i], 我再
ppCmdArg[i] = new char[vCmdSet[i].length() + 1];
由於參數不可能每個長度都相同 因此new出來的結果長度都不相同
3. 接下來我再把vector裡面儲存的參數字串拷貝到new出來的char* ppCmdArg[i]
4. 如果有傳環境變數我也是做一樣的處理 這次範例沒有可以無視
5. 接著就把ppCmdArg給execve當參數呼叫process
結果我發現程式在結束的地方 我做delete[] array出了問題
然後我把這段程式碼加了printf做debug
看到了無法理解的結果
輸出:
作者: nh60211as   2020-11-10 20:32:00
ppCmdArg[vCmdSet[i].length()] = 0; 你這行是做什麼的還有你都寫C++了有什麼必要是要用C-style字串嗎
作者: Lipraxde (Lipraxde)   2020-11-10 20:42:00
L44、L62 在幹嘛?省略 code 可以,但是請弄一個 minimal working example 出來。不然看 code 還要腦補省略的部分有沒有可能出問題很累,又不是在猜燈謎 = =
作者: nh60211as   2020-11-10 21:28:00
字串的結尾是ppCmdArg[i][vCmdSet[i].length()]
作者: ucrxzero (RX-0)   2020-11-10 21:28:00
58行 ppCmdArg[vCmdSet[i].length()] = 0;錯兩個地方
作者: stucode   2020-11-10 21:29:00
其實一樓已經說出問題所在了,L58
作者: nh60211as   2020-11-10 21:29:00
ppCmdArg[x]是char** ppCmdArg的第x個位置
作者: ucrxzero (RX-0)   2020-11-10 21:29:00
ppCmdArg[i][vCmdSet[i].length()] = \0;不是0 是null才對剛好其他人都有解出來請樓主幫我把整個有我的推文全刪還有strcpy本來就會複製\0過去了要不然strcpy這麼聰明就不會跟get一樣列為危險函示了
作者: Lipraxde (Lipraxde)   2020-11-10 22:01:00
仔細對照一下 L56、L58、L61,再想想看 L58 真的有寫出你想要的意思嗎?當 i = 2 or 3 的時候 L58 做了什麼?另外 L110~L129 建議是拿 man waitpid 裡的範例來改
作者: nh60211as   2020-11-10 22:21:00
抱歉,看到後面的code應該真的只能用char**來寫
作者: ucrxzero (RX-0)   2020-11-10 23:40:00
C++寫法 (可過): vector<char*> char_vtrvector<char*> env_vtrexecve(proc_name, &char_vtr, &env_vtr)execve(proc_name, &char_vtr[0], &env_vtr[0])但不建議使用
作者: Killercat (殺人貓™)   2020-11-27 14:25:00
好像並不是所有的STL都保證data記憶體位置在前面建議用std::vector::data取得資料段的pointer比較保險

Links booklink

Contact Us: admin [ a t ] ucptt.com