[問題] vector<char*>, strtok 與 free

看板C_and_CPP (C/C++)作者 (TeA)時間12年前 (2013/12/16 16:41), 編輯推噓3(3019)
留言22則, 2人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) VC++ 2012 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) NO 問題(Question): 我想我需要釐清觀念,這個問題困擾我三天了 我現在遇到memory leak (ML)的問題。 透過VC內建的memory leak detectiont,我知道程式哪裡有Memory leak 但是我有一個地方搞不清楚 容器用到char* ,例如 vector<char*> 或map<char*,int> 當我用 push_back(char*資料) 或 insert(char*資料,1) 在我下列的程式碼,我一個一個去把Vector裡面的char*刪掉是可以,才不會ML 但是我以為我可以直接free(file_content2)就好, 我的認知是 file_content2 一個連續的大空間 vector<char*>裡面的元素只是指到file_content2的片段 例如"I LOVE YOU"經過strtok之後 "I" "\0" "LOVE" "\0" "YOU" vector分別指到I,LOVE,YOU,那我應該直接free file_content2就好了吧? 可是這樣做的話會出錯,不能free file_content2 但是不free的話,最後VC跟我說file_content2 ML了 可是我找不到哪裡可以free它 :( 希望各位板友們能指引我一下 以下是片段關鍵程式碼 char *file_content2 = (char*) malloc(...); strcpy(file_content2,file_content); //file_content不想被strtok破壞 vector<char*> v = explode("\n",file_content2); //free(file_content2) 加上這行會出錯,就錯在這一行,不是之後的free(v[i]) printf("v %X, %X\n",v[0],relation_list_content2); //上一行會列印 不一直的位置 for(i=0;i<v.size();++i) free(v[i]); //這樣OK //exlode程式碼 //出處 //http://ubuntuforums.org/showthread.php?t=1272422 (我有修改過) std::vector<char*> explode(char *target, char *str) { std::vector<char*> v; char *pch,*last; pch = strtok_s(str,target,&last); while (pch != NULL) { v.push_back(strdup(pch)); pch = strtok_s(NULL, target,&last); } return v; } 餵入的資料(Input): oooo,xxxx,1\n aaa,bbbb,1\n 預期的正確結果(Expected Output): 沒有Memory leak 錯誤結果(Wrong Output): free錯誤及memory leak 補充說明(Supplement): -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 202.215.28.49 ※ 編輯: cjoe 來自: 202.215.28.49 (12/16 16:43) ※ 編輯: cjoe 來自: 202.215.28.49 (12/16 16:44)

12/16 16:45, , 1F
你完全弄反了, 不應該 free(v[i]) 才對
12/16 16:45, 1F

12/16 16:45, , 2F
可是不這樣的話會memory leak
12/16 16:45, 2F

12/16 16:46, , 3F
之所以沒事除了 v[0] 會跟該 free 的位址 file_content2 同
12/16 16:46, 3F

12/16 16:46, , 4F
其他的 v[i] 被亂 free 掉了的關係
12/16 16:46, 4F

12/16 16:46, , 5F
碰巧沒事
12/16 16:46, 5F
※ 編輯: cjoe 來自: 202.215.28.49 (12/16 16:47)

12/16 16:47, , 6F
咦等一下, 你抄的程式裡有 strdup...
12/16 16:47, 6F

12/16 16:47, , 7F
這樣的話兩者都要 free 掉才行
12/16 16:47, 7F

12/16 16:49, , 8F
free(file_content2) 的錯誤訊息是什麼?
12/16 16:49, 8F

12/16 16:49, , 9F
原來是 strdup @_@!! 可是我file_content2 free會出錯
12/16 16:49, 9F

12/16 16:52, , 10F
HEAP[RP_knockout.exe]: Heap block at OO modified at XX
12/16 16:52, 10F

12/16 16:52, , 11F
然後VC跳出來的CODE指在 if (retval == 0) //free.c
12/16 16:52, 11F

12/16 17:04, , 12F
這様答案不是 ML 而是陣列超出範圍, 你的字串太長了 XD
12/16 17:04, 12F

12/16 17:06, , 13F
這個訊息是 heap block corrupt 表示那塊記憶體外附近給系統
12/16 17:06, 13F

12/16 17:06, , 14F
我把strdup拿掉了,現在vector跟file_content2位置一樣了
12/16 17:06, 14F

12/16 17:06, , 15F
存資料的地方被寫入了 這最常見就是陣列超標
12/16 17:06, 15F

12/16 17:07, , 16F
!!!!! 我好像有方向了!!
12/16 17:07, 16F

12/16 17:13, , 17F
呃,難道是我在malloc時 忘了+1放 "\0" ...
12/16 17:13, 17F

12/16 18:15, , 18F
順帶澄清一個誤會: VC 確實是會在 (debug build 時的) free
12/16 18:15, 18F

12/16 18:15, , 19F
裡檢查一些東西, 然後當不對勁時就會噴錯誤訊息
12/16 18:15, 19F

12/16 18:16, , 20F
但是那不是用來偵測 memory leak 的, 而是偵測越界寫入的
12/16 18:16, 20F

12/16 18:16, , 21F
memory leak 並沒有這麼方便的偵測法...
12/16 18:16, 21F

12/16 19:03, , 22F
3Q!
12/16 19:03, 22F
文章代碼(AID): #1IhhpJ9_ (C_and_CPP)
文章代碼(AID): #1IhhpJ9_ (C_and_CPP)