CStringオブジェクトが作成されるメモリ領域について – プログラミング – Home

CStringオブジェクトが作成される...
 
通知
すべてクリア

[解決済] CStringオブジェクトが作成されるメモリ領域について


ミミ
 ミミ
(@ミミ)
ゲスト
結合: 24年前
投稿: 63
Topic starter  

いつもお世話になります。ミミです。
環境は、Win2000、eMbedded Visual C++4.0、MFC使用です。

前回の私のスレッド「スタック領域について」からの派生質問です。
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200601/06010008.txt

OnHoge()::OnButton1(){
CString sMsg;
sMsg = あいうえお;
}

と記述した時、

【MSDNより引用】----
ヒント CString オブジェクトはできる限りヒープ領域ではなく、フレーム上に確保します。
これは、メモリの消費を抑え、引数の渡し方を単純化します。
-------------------

とありますが、ここでいう「フレーム上」というのはどこの空間の事を言うのでしょうか?
スタックの事を言っているのでしょうか?

# 上記の sMsg を sizeof で計っても4バイトと返って来ます。
# どんな文字列を代入しても、結果は4バイトです。
# 個人的には、sMsgはアドレスしか持っておらず、「そのもの」がフレームと呼ばれる
# メモリ領域に存在していると考えています。

以上よろしくお願いいたします。


引用未解決
トピックタグ
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> 上記の sMsg を sizeof で計っても4バイトと返って来ます。
これは、sizeof(CString)です。

文字の長さは CString::GetLength で取ってください。
それとも、実際使っているメモリを知りたいのでしょうか?
(CStringはなんか複雑だったような。。。)


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

MFCのソースコードを追っかければわかるんだけど、
CStringに関してはライブラリ内部で独自のメモリ管理をやってるみたい。
文字列を真面目にallocateすると小さく刻まれがちだから、
独自のメモリ・プールを用意して、そこから切り出して使ってますね。
それをフレームと称しているんじゃないかしら。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

原文だと、

http://msdn.microsoft.com/library/en-us/wcemfc/htm/cstring_8.asp

| Tip Where possible, allocate CString objects on the stack rather
| than on the heap. This saves memory and simplifies parameter passing.

ですね。

オブジェクトそのものの確保場所については、
特に CString 固有の特徴があるようには思えませんけど、
なんで、こんなことに言及してるんでしょうか。


返信引用
ミミ
 ミミ
(@ミミ)
ゲスト
結合: 24年前
投稿: 63
Topic starter  

ミミです。

Blue様、επιστημη様、dairygoods様、早速のお返事ありがとうございます。

あるゴミプログラムを作っていた際、本来であればヒープ上に領域を作成して文字列を代入する
所を
(ゴミプロという事で)少々横着し、OnButton1()の中にローカル変数としてCStringオブジェク
トを作り、
そこに代入していました。
# もちろん、正規に開発しているプログラムでは、予めヒープ上に領域を作成し、そこへ文字列
代入等を
# 行っています。

ここで、前回のスレッドにもありますとおり、スタックサイズは CE では 58KB という事を思
い出し、
CString型のオブジェクトに例えばたくさんの文字列を代入した場合、それはスタックサイズを
圧迫するのでは
ないかと思って調査したところ、sizeofでも4としか返って来なかった・・・という経過で
す。

その上で、
>Blue様
>実際使っているメモリを知りたいのでしょうか?
はい、メモリの使用量を知りたかった為です。文字列長ではありません。ご指摘ありがとうござ
いました。

>dairygoods様
>なんで、こんなことに言及してるんでしょうか。
普通なら考えもしない事なのかも知れませんが、スタック圧迫によるスタックオーバーフローの
問題に
遭遇した為、ちょっとの事でもつい過敏になって考えてしまった為です。
CStringは簡単に使えて便利なクラスではありますが、使いすぎてたくさんの文字列を代入する
と、
結局はスタックを消費してしまうのかと思った為です。

>allocate CString objects on the stack rather than on the heap.
ヒープよりもスタックに確保されるような事が書かれていますね。
という事は、やはりCStringも使いすぎには注意しないといけないという事ですね。

>επιστημη様
ソースコードを追っていただき、ありがとうございます。
なるほど…、独自に別処理しているとするなら、私が定義したsMsgにはやはりアドレスしか持
たないと
納得できます。
dairygoods様の提示してくれた上記と合わせて考えると、このフレーム領域はスタック領域に
配置されると解釈できます。


返信引用
ミミ
 ミミ
(@ミミ)
ゲスト
結合: 24年前
投稿: 63
Topic starter  

改行位置が悪く読みにくくなってしまったこと、お許しください。

また、dairygoods様の提示していただいたURLをたどって、
下記URLを参考にさせていただきました。

http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/wcemfc/htm/cstring.asp


返信引用
tetrapod
 tetrapod
(@tetrapod)
ゲスト
結合: 21年前
投稿: 830
 

>>allocate CString objects on the stack rather than on the heap.
>ヒープよりもスタックに確保されるような事が書かれていますね。
いや翻訳が違う。
ここは命令形なので「ヒープではなくスタックに取れ」という意味。
最初の邦訳が「フレーム」と呼んでいる領域はスタックのことでしょう。
# new せず auto で作れ、ということだろう。あたりまえ。わざわざ言及する内容とも思えな
い。

sizeof CString が 4 なのはそういう実装にしてあるから。
メンバ変数がポインタ1個だけ、という実装に故意にしてあるため。

既にコメントがあるように CString 1個をスタックに取ると、消費スタック量は4
実際の文字列本体は独自に取ったヒープに入ります。

ああ、だから auto で取った CString でも文字列本体はヒープに行くから、
「ヒープに文字列を取りたいからという理由で CString 自体を new する必要は無い」
ということを主張したいのかも >> MS


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

CStringT型ですが、

ttp://www.microsoft.com/japan/msdn/library/default.asp?
url=/japan/msdn/library/ja/vccore/html/vcconMemoryManagementCStringT.asp


返信引用
Kerry
 Kerry
(@Kerry)
ゲスト
結合: 20年前
投稿: 192
 

つまりこういうことでしょう。

CStringクラスのインスタンス自身はポインタ変数1個だけで、
文字列本体は別途ヒープ上に作成されます。
文字列は参照カウントを使って管理されるので、同一文字列を
指すCStringクラスのインスタンス間で共有されます。

以下のようにCStringクラスのインスタンスを引数として取る
場合は、引数の受け渡しはスタック上でのポインタの受け渡し
で済み、文字列本体をコピーしないので効率的です。

void Foo()
{
CString a = あいうえお;
Bar(a);
}

void Bar(CString b) // <-- a と同じ文字列実体を参照する
{
AfxMessageBox(b);
}


返信引用
ミミ
 ミミ
(@ミミ)
ゲスト
結合: 24年前
投稿: 63
Topic starter  

ミミです。

tetrapod 様、ITO 様、Kerry 様、
ご返信ありがとうございます。

>tetrapod 様
自分の英文の誤解釈に対するご指摘、ありがとうございました。

ITO 様が提示してくれましたリンク先に
>一般的なアプリケーションでは、このメモリ割り当て方法で十分です。
と記載されていました。
CString を 普通に使う分には、(今までもそうでしたが…)特にメモリについて考える必要は
ないという事がわかりました。

Kerry 様のご意見にもあるとおり、
やはり CString インスタンスはアドレスしか持たず、
(επιστημη 様もご指摘してくれましたが)実際のメモリ管理等は、
CString クラスの中で処理していると割り切って考えることにします。

# そもそも MFC というのが、ブラックボックス的な要素ですし・・。

>【ミミ 2006/01/27(金) 15:33:27】
>このフレーム領域はスタック領域に配置されると解釈できます。
            ↓
「このフレーム領域(文字列そのもの)はヒープ領域に配置されると解釈できます。」
と言うことで、本件はこれで解決とさせていただきます。

皆様、ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました