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

看板C_and_CPP (C/C++)作者 (動き出す時間...)時間4年前 (2020/11/10 19:53), 4年前編輯推噓3(3022)
留言25則, 4人參與, 4年前最新討論串1/2 (看更多)
開發平台(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 看到了無法理解的結果 輸出: -------------new-------------- ppCmdArg[0] = ffmpeg ppCmdArg[1] = -vsync ppCmdArg[2] = 0 ppCmdArg[3] = -i ppCmdArg[4] = file.cfg ppCmdArg[5] = Compare.yuv -------------new end-------------- -------------test 1-------------- ppCmdArg[0] = ffmpeg ppCmdArg[1] = (null) ppCmdArg[2] = (null) ppCmdArg[3] = -i ppCmdArg[4] = file.cfg ppCmdArg[5] = Compare.yuv ------------test 1 end-------------- ------------test 2-------------- ppCmdArg[0] = ffmpeg ppCmdArg[1] = (null) ppCmdArg[2] = (null) ppCmdArg[3] = -i ppCmdArg[4] = file.cfg ppCmdArg[5] = Compare.yuv -------------test 2 end-------------- vCmdSet size = 6 ppCmdArg[0] = ffmpeg ppCmdArg[1] = (null) ppCmdArg[2] = (null) ppCmdArg[3] = -i free(): invalid pointer Aborted (core dumped) 我new完, copy字串進去 可以正確printf 然後馬上在test 1區塊全部重印一次 結果ppCmdArg[1], ppCmdArg[2]變成NULL? 請教一下各位先進 是否我犯了什麼錯?或者gcc編譯的參數錯了嗎? 我用的是 -O2 -W -fPIC 先感謝各位了 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 210.242.38.175 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1605009218.A.846.html

11/10 20:32, 4年前 , 1F
ppCmdArg[vCmdSet[i].length()] = 0; 你這行是做什麼的
11/10 20:32, 1F

11/10 20:34, 4年前 , 2F
還有你都寫C++了有什麼必要是要用C-style字串嗎
11/10 20:34, 2F
我把字串結尾設定為\0 您的意思是要怎麼用C++改寫比較好呢?

11/10 20:42, 4年前 , 3F
L44、L62 在幹嘛?省略 code 可以,但是請弄一個 minim
11/10 20:42, 3F
L42就是我說的每一個char* ppCmdArg[i]去new char array L62一樣是把字串結尾設定為\0

11/10 20:42, 4年前 , 4F
al working example 出來。不然看 code 還要腦補省略的
11/10 20:42, 4F

11/10 20:42, 4年前 , 5F
部分有沒有可能出問題很累,又不是在猜燈謎 = =
11/10 20:42, 5F
已經把完整code重新上傳 請多多指教 感恩 ※ 編輯: Keitaro (210.242.38.175 臺灣), 11/10/2020 21:22:06 ※ 編輯: Keitaro (210.242.38.175 臺灣), 11/10/2020 21:22:29

11/10 21:28, 4年前 , 6F
字串的結尾是ppCmdArg[i][vCmdSet[i].length()]
11/10 21:28, 6F

11/10 21:28, 4年前 , 7F
58行 ppCmdArg[vCmdSet[i].length()] = 0;
11/10 21:28, 7F

11/10 21:28, 4年前 , 8F
錯兩個地方
11/10 21:28, 8F

11/10 21:29, 4年前 , 9F
其實一樓已經說出問題所在了,L58
11/10 21:29, 9F

11/10 21:29, 4年前 , 10F
ppCmdArg[x]是char** ppCmdArg的第x個位置
11/10 21:29, 10F

11/10 21:29, 4年前 , 11F
ppCmdArg[i][vCmdSet[i].length()] = \0;
11/10 21:29, 11F

11/10 21:29, 4年前 , 12F
不是0 是null才對
11/10 21:29, 12F

11/10 21:30, 4年前 , 13F
剛好其他人都有解出來請樓主幫我把整個有我的推文全刪
11/10 21:30, 13F
好喔

11/10 21:32, 4年前 , 14F
還有strcpy本來就會複製\0過去了
11/10 21:32, 14F

11/10 21:32, 4年前 , 15F
要不然strcpy這麼聰明就不會跟get一樣列為危險函示了
11/10 21:32, 15F

11/10 22:01, 4年前 , 16F
仔細對照一下 L56、L58、L61,再想想看 L58 真的有寫出
11/10 22:01, 16F

11/10 22:01, 4年前 , 17F
你想要的意思嗎?
11/10 22:01, 17F

11/10 22:02, 4年前 , 18F
當 i = 2 or 3 的時候 L58 做了什麼?
11/10 22:02, 18F
恍然大悟 唉我真的是蠢... 怎麼會這樣寫 看到樓上幾位的點名真的是覺得自己蠢到家了犯這種錯誤... 可見自己二維陣列的觀念生疏了QQ 非常感謝各位的指教 ※ 編輯: Keitaro (210.242.38.175 臺灣), 11/10/2020 22:13:53

11/10 22:12, 4年前 , 19F
另外 L110~L129 建議是拿 man waitpid 裡的範例來改
11/10 22:12, 19F
瞭解

11/10 22:21, 4年前 , 20F
抱歉,看到後面的code應該真的只能用char**來寫
11/10 22:21, 20F
是的 我真的想不出其他寫法 他參數型態要求char**然後我要寫傳任意參數的 想來想去也只能這樣寫 ※ 編輯: Keitaro (210.242.38.175 臺灣), 11/10/2020 22:31:14

11/10 23:40, 4年前 , 21F
C++寫法 (可過): vector<char*> char_vtr
11/10 23:40, 21F

11/10 23:41, 4年前 , 22F
vector<char*> env_vtr
11/10 23:41, 22F

11/10 23:41, 4年前 , 23F
execve(proc_name, &char_vtr, &env_vtr)
11/10 23:41, 23F

11/10 23:42, 4年前 , 24F
execve(proc_name, &char_vtr[0], &env_vtr[0])
11/10 23:42, 24F

11/10 23:43, 4年前 , 25F
但不建議使用
11/10 23:43, 25F
文章代碼(AID): #1Vgdz2X6 (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1Vgdz2X6 (C_and_CPP)