討論區快速選單
知識庫快速選單
傑米的攝影旅遊筆記 軟體開發過程中有哪些資安漏洞? 程式設計俱樂部Facebook粉絲團
[ 回上頁 ] [ 討論區發言規則 ]
memory指標問題
更改我的閱讀文章字型大小
作者 : teldeanmac85(Dean)
[ 貼文 28 | 人氣 3110 | 評價 0 | 評價/貼文 0 | 送出評價 4 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2017/2/20 上午 09:32:40
我可以利用這種方式將記憶體正確release掉嗎 ?
當按了多次Button2及Button3後將local及global指標存在global vector內
在適當時機時按下Button4後將所有memory release
以下為source code,是否為可這樣做.

int *p2 = NULL ;
vector<int*> vtr_int_list ;

void fff(int* &a)
{
   a = new int [10000000];
   vtr_int_list.push_back(a) ;

   int n;
   for(n=0;n<10000;n++)
   {
     *(a+n) = n ;
   }

}


void __fastcall TForm1::Button2Click(TObject *Sender)
{
   int *p1 = NULL ;
   fff(p1);
   fff(p2);

}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
   int *p1 = NULL ;
   fff(p1);
   fff(p2);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(TObject *Sender)
{
   int n;
   for(n=0;n<vtr_int_list.size();n++)
   {
     char ss[512] = {'\0'};
     sprintf(ss,"%p",vtr_int_list[n]);
     Memo1->Lines->Add(ss);
     delete [] vtr_int_list[n] ;
     vtr_int_list[n] = NULL ;
   }
   vtr_int_list.clear();
}
//------------------------------------------------------------------------
作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 386 | 人氣 0 | 評價 1770 | 評價/貼文 4.59 | 送出評價 17 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人teldeanmac85註記此篇回應為很有道理 2017/2/20 下午 01:31:52
就你貼的程式來看,應該是可以這樣用。
因為只是示例程式,不知道你實際的用途目的,所以無從評論;但總覺得實際上可以寫的更精減明白,有些問題應該可以讓他根本不出現。
作者 : teldeanmac85(Dean)
[ 貼文 28 | 人氣 3110 | 評價 0 | 評價/貼文 0 | 送出評價 4 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2017/2/20 下午 02:18:24
....總覺得實際上可以寫的更精減明白...
請問一下精簡明白的方式是??可以提供我學習嗎??

其實我測試的東西是為了解決如下的問題
要達到修改最少的目的

[原始程式碼]
但下列有一個問題是fgets為雖然為單行讀取,但是若此行超過512字元時
必須再判斷再讀取串接字串為單行,因此fgets在開發時多處有應用到為避免大伏度修改
實作一個 ffgets 來取代 fgets
char str[512];
while (fgets(str, 512, stream) != NULL)
{
   ....
}

[修改後]
vector<char*> vtr_int_list ;
char *str2 ;
void read()
{
   char *str ;

   while (ffgets(str, 512, stream) != NULL)
   {
     ...
   }
   while (ffgets(str2, 512, stream) != NULL)
   {
     ...
   }
}

char* ffgets(char* &s,int n,FILE *f)
{
     ...
     s = new char [...] ; //這邊會算出字串長度將記憶體建立出來
     ...
     vtr_int_list.push_back(s) ; 最後再用vector記下指標位置
}

void exit(void) //當程式結束前呼叫exit
{
    int n;
    for(n=0;n<vtr_int_list.size();n++)
    {
     delete [] vtr_int_list[n] ;
     vtr_int_list[n] = NULL ;
    }
    vtr_int_list.clear();
}


以上為大概的原意,這樣只要改掉原有的fgets->ffgets
將變數array改成指標即可 , 但有一個很大的問題是若ffgets使用
大量時可能會有記憶體爆掉的問題,目前仍持續再想想其他辦法....
作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 386 | 人氣 0 | 評價 1770 | 評價/貼文 4.59 | 送出評價 17 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人teldeanmac85註記此篇回應為最佳解答 2017/2/20 下午 05:47:54
bool get_file_line(std::string &text, FILE *file)
{
    text.clear();

    bool have_line_end = false;
    bool end_of_file = false;
    while( !have_line_end && !end_of_file )
    {
     char buf[512] = {0};
     end_of_file = !fgets(buf, sizeof(buf), file);

     text.append(buf);
     have_line_end = ( text[text.length()-1] == '\n' );
    }

    text.length() || !end_of_file;
}

std::vector<std::string> read_file(FILE *file)
{
    std::vector<std::string> list;

    std::string line;
    while( get_file_line(line, file) )
     list.push_back(line);

    return list;
}

這樣,緩衝用完就放,無需囤積。
並且我讓 STL 自己去做物件管理,當我使用的字串列表離開作用域後就會自己被釋放掉,完全無需我操心。
作者 : teldeanmac85(Dean)
[ 貼文 28 | 人氣 3110 | 評價 0 | 評價/貼文 0 | 送出評價 4 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2017/2/21 上午 09:31:51
hi~ ice_emissary
謝謝你的回覆

利用函式字串參數型態使用string方法我有想過....但code仍要修改很多
所以並沒有考慮,不過你提供的例子是最佳的解法

因fgets在我這邊有大量的使用算一算有300多個吧~其參數都是有char array字串
後續也針對此變數會做很多字串處理,一一修改可能超過幾萬行,所以改用string會改
到手軟
作者 : ice_emissary(燃燒的大地) 貼文超過200則
[ 貼文 386 | 人氣 0 | 評價 1770 | 評價/貼文 4.59 | 送出評價 17 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人teldeanmac85註記此篇回應為很有道理 2017/2/21 上午 10:01:17
其實這並不是最佳解法,事實上 C++ 還有一個標準函式叫 getline,使用它的話就連第一個函式都不需要了!

你的問題其實是整個程式結構的問題,因為程式結構混亂,你不知道哪些字串在什麼時候使用完畢而可以釋放,因此你只好把所有的字串全部囤積下來到程式結束時再釋放,那麼記憶體使用會一直增長的問題就屬自然了!
 板主 : 徵求中
 > C++ Builder - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - C++ Builder - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
C++ Builder
1 windblown 5420 
2 Raynor 3120 
3 阿泰 2980 
4 workman 1650 
5 Linkin 1360 
6 CrazyStar 1260 
7 青衫 1160 
8 jonay 1080 
9 charlie 900 
10 小呆 770 
C++ Builder
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2018 程式設計俱樂部 http://www.programmer-club.com.tw/
0.0625