- PR -

MFC CString の大量連結

投稿者投稿内容
takashi
ベテラン
会議室デビュー日: 2004/02/12
投稿数: 79
お住まい・勤務地: 東京
投稿日時: 2004-02-26 17:53
いつも参考にさせていただいてます。

MFCのCString について質問です。
エディットコントロールに改行区切りの長いテキストを表示するために、FOR文でまわしながら大量のCStringオブジェクトを+=で連結しているのですが、これはメモリ効率的には問題ないのでしょうか?Javaでこのような処理をする時はStringBufferクラスのappendメソッドを用いて、大量のStringオブジェクトを作らないようにすると思うのですが、MFCで同じ機能を持ったクラスやメソッドは存在するのでしょうか?ヘルプでいろいろ探したのですが見当たらないようです。または、StringBufferに相当するような処理をCStringがしてくれてるのでしょうか?
何か知ってる方、ご教授していただければ幸いですm(_ _)m
弟子
会議室デビュー日: 2004/02/03
投稿数: 11
投稿日時: 2004-02-26 19:46
CStringは内部的にCSimpleStringTを使用していてその中の処理をのぞいてみると・・・
文字のサイズの計算などを行って最終的にmemcpyで連結を行っています。
その間にメモリ関係のチェックなどの処理は行っていますが・・・基本的にメモリ効率には影響ないでしょう。

cstring.h
atlsimpstr.h

このソースを見ることをお勧めします。
takashi
ベテラン
会議室デビュー日: 2004/02/12
投稿数: 79
お住まい・勤務地: 東京
投稿日時: 2004-02-27 10:01
すばやい回答ありがとうございます^^
なるほど、メモリ効率に影響はないと聞いてほっとしました。
cstring.h atlsimpstr.h のソースをのぞいてみることにします。

ありがとうございましたm(_ _)m
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2004-02-27 10:54
ども、ほむらです。
ぽそっと^^;;;;
----
直接DDEとWindowメッセージ(EM_????)で処理したらだめなの?とか思ってみたり
コントロール使っていて大量のCStringとかあまり結びつかないな〜。

#たんに、「大量のCStringオブジェクト」という単語が気になってみたり。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-02-27 11:00
???
 「メモリ効率的な問題」って、何ですか?どういうものを「問題」としますか?また、弟子さんのどの言葉から、どのように判断して、takashiさんの考える問題に対して影響がないと判断されたのでしょう?

 内部でmallocでメモリを確保しているなら、フラグメンテーションが起きる可能性はありますよ?CStringクラスのインスタンスがたくさんできるという問題は無いにしても、メモリの使用効率は問題が発生する可能性があるのではないですか?

・・・メモリ周りをどのように実装しているかに因りますけど。

 例えば、.NETの場合、stringクラスに対して+演算子が使えます。しかし、StringBuilderクラスを使用するように推奨されています。特に、文字列の最大長があらかじめわかっているなら、Lengthプロパティで先に設定しておくことができます。これは、その長さのメモリを先に確保することによって、メモリを逐次確保するための時間を抑えたり、使用効率を良くすることが目的です。

 MFCのCStringクラスがどのように実装されているのか見ていませんが、私は弟子さんがメモリ確保について言及されていないため、問題があるかもしれないと思います。
takashi
ベテラン
会議室デビュー日: 2004/02/12
投稿数: 79
お住まい・勤務地: 東京
投稿日時: 2004-02-27 11:37
たくさんの回答ありがとうございます^^

引用---------------------------------------------------------------------------
内部でmallocでメモリを確保しているなら、フラグメンテーションが起きる可能性はありますよ?CStringクラスのインスタンスがたくさんできるという問題は無いにしても、メモリの使用効率は問題が発生する可能性があるのではないですか?
-------------------------------------------------------------------------------
僕が気にしているのはまさにそういうことなんです。やっぱり、フラグメンテーションがおきるんですね^^;

StringBuilderクラスというものがあるんですね。ヘルプで調べてみたところ、JavaでいうところのStringBufferクラスにあたるものですよね。こういうのを探してたんですが….NET Framework なんですね;; 今開発してるプログラムは .NET Framework がない環境で動くことを想定してるものなので使えないっぽいんですが…;;

引用 ------------------------------------------------------------------
直接DDEとWindowメッセージ(EM_????)で処理したらだめなの?とか思ってみたり
コントロール使っていて大量のCStringとかあまり結びつかないな〜。
-----------------------------------------------------------------------
経験不足でどういうことかわからないんですが、別のやり方があるということですよね。DDEなどで検索するなりして調べてみたいと思います。

どちらにしても、今のコーディングではあまりよくないようなので皆さんの意見を参考にしてもっといい方法を探してみます^^
弟子
会議室デビュー日: 2004/02/03
投稿数: 11
投稿日時: 2004-02-27 12:13
弟子です。
>>Jittaさん
私は「メモリ効率の悪さ」を「オブジェクトのインスタンス生成時のオーバーヘッド」と
解釈して返答をしました。
(実際C++のテンプレートオブジェクトの生成はオーバーヘッドがかかるのですが、Java等と
比べてほとんど無視できると判断しました。)
その他メモリフラグメンテーション等は考慮していません。

もし、先行してメモリを確保する必要があるなら・・・CStringArrayというものがあります。
(ただし、使ったことがありませんが・・・(汗))
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-02-27 12:22
引用:

takashiさんの書き込み (2004-02-27 11:37) より:

僕が気にしているのはまさにそういうことなんです。やっぱり、フラグメンテーションがおきるんですね^^;


 いや、だから、

>  MFCのCStringクラスがどのように実装されているのか見ていませんが、
> 私は弟子さんがメモリ確保について言及されていないため、
> 問題があるかもしれないと思います。

と書いたように、内部でどのような処理をしているかわからないので、「可能性」としてあげているだけです。また、もしCStringがmallocを使用していても、

> ・・・メモリ周りをどのように実装しているかに因りますけど。

なんです。

 私が知っている、10年前のSunOSでは、mallocの動作は次のようでした。

割当可能なメモリ→○○○○○○○○○○
未使用→○
使用中→●
境界→|

5割当:●●●●●|○○○○○
3割当:●●●●●|●●●|○○
5解放:○○○○○|●●●|○○
6割当:エラー!!

5が解放され、2は未割当なので、計7の空きがあるのですが、使用している箇所を越えての割当はできませんでした。

しかし、実装によっては、

6割当:◎◎◎◎◎|●●●|◎|○

のように、フラグメンテーションが発生するけれども、メモリを割り当てるようなものもあります。当然、番地が飛びますが、メモリアクセスをマネージャ経由にすることで、アプリケーション側は気にしなくて済みます。

また、次のような実装にすることも可能です。

6割当:領域がない→デフラグする(●●●|○○○○○○○)
6割当:●●●|●●●●●●|○


 mallocの動作は、メモリ割付要求をしたものから見て「連続したメモリ」が割り当てられればよいので、そういう結果が得られれば、どのように実装しても、それは処理系の自由です。3番目に示したような実装であれば、デフラグの時間はかかりますが、フラグメンテーションは発生しません。

 人のいうことを鵜呑みにしてはいけません。
#そうされそうだったから「思う」でくくったのだが、やはり。。。

#####
 そういえば、C++ Builderにも同様なクラスがあったし、STLにも何かあったような?1年使わないと忘れるとは・・・

スキルアップ/キャリアアップ(JOB@IT)