CArrayのGetAt()を使うとアサートが発生してしまいます。

[戻る]
にゃも 2005/05/18(水) 16:55:34
こんにちわ。
にゃもといいます。

CArrayを使用してデータを取得し、
その中のデータをGetAt()を使って取得したいと思っています。

CArray<LPSTR,LPSTR> m_caOfFolder;
CArray<LPSTR,LPSTR> m_caOfPrefix;

m_pPage1->GetPalam(&m_caOfFolder,&m_caOfPrefix);

LPSTR str;
str = (char*)malloc(O2G_PATH_MAX);
str = m_caOfFolder.GetAt(1);

というように書いているのですが、
どこが原因なのかが分かりません。
しかもなぜか、アサートが発生するときは、
上記のコードが書いてある関数を呼んでいないときに発生します。
GetAt()をコメントアウトすると、アサートは発生しません。

色々試したのですが、
どうしても原因がわかりません。

何か思い当たるところがあったら、
ご教授ください。
よろしくお願いします。

επιστημη 2005/05/18(水) 17:03:52
> str = m_caOfFolder.GetAt(1);

この時点でm_caOfFolderには少なくとも2個の要素が入っていますよね?

REE 2005/05/18(水) 17:14:53
この後で、free(str)としていませんか?

にゃも 2005/05/18(水) 17:20:59
早速のお返事ありがとうございます。

要素は2つ以上あり、
freeもしていません。

ちなみに、mallocは
str = (LPSTR)malloc(O2G_PATH_MAX);
としていました。
すいません。

よろしくお願いします。

REE 2005/05/18(水) 17:34:32
caOfFolderへ要素を追加した後に、その文字列データを破棄していませんか?
caOfFolderは文字列へのポインタを保持するだけで、文字列の内容は保持しません。


>str = (char*)malloc(O2G_PATH_MAX);
>str = m_caOfFolder.GetAt(1);

この場合1行目で設定した値は、2行目で上書きされるので、
mallocした意味がないばかりか、そのメモリは確実にリークします。
もし、確保したメモリに文字列をコピーしたいのであれば、2行目はstrcpyを使ってくだ
さい。

Blue 2005/05/18(水) 17:41:03
> CArray<LPSTR,LPSTR> m_caOfFolder;
CStringArrayを使わないのは何か問題があるのでしょうか?
結局mallocするならばそっちのほうがベターだと思うのですが。

にゃも 2005/05/18(水) 17:46:19
strcpyを使ってみましたが、だめでした・・・。
何か、もっと別なところが原因のような気もします。

もう少し粘ってみようと思います。

Blue 2005/05/18(水) 17:56:15
>caOfFolderへ要素を追加した後に、その文字列データを破棄していませんか?
のところのソースを表示してくれませんか?
ポインタでCArrayの要素を持つ場合はそのポインタ指すメモリの寿命を考慮しなければ
なりません。

# ポインタでもつならば CTypedPtrArray のほうがいいと。

にゃも 2005/05/18(水) 18:09:03
要素を追加しているソースは

for(int i=0;i<m_office6List.GetItemCount();i++)
{
char chDataFolder[128];
char chPrefix[128];

CString csDataFolder;
CString csPrefix;

csDataFolder = m_office6List.GetItemText(i,0);
csPrefix = m_office6List.GetItemText(i,1);

lstrcpy(chDataFolder,csDataFolder);
lstrcpy(chPrefix,csPrefix);

m_caFolder->Add(chDataFolder);
m_caPrefix->Add(chPrefix);
}

です。

Blue 2005/05/18(水) 18:15:07
>CString csDataFolder;
>CString csPrefix;
これらの変数(ローカル変数)の寿命は for分のスコープをでると終わります。

この処理をおわってからその文字データを参照したい場合は
動的にメモリを割り当てる必要があります。(mallocやnew)
# 当然つかわなくなったらdeleteしなければなりませんが。

# CStringArrayならばカナーリ楽チンですけどね。

REE 2005/05/18(水) 18:19:55
>>caOfFolderへ要素を追加した後に、その文字列データを破棄していませんか?

まさにこうなっています。

m_caOfFolderに格納されているのは既に無効になっているchDataFolderへのポインタで、
しかも全要素が同じ値です。
# m_caPrefixも同様


現状のまま変更することも可能では有りますが、CStringArrayに変更されることをお勧め
します。

にゃも 2005/05/18(水) 18:30:03
[[解決]]
REEさん、Blueさん、ありがとうございます!
教えていただいたように変更してみたら、
いとも簡単に解決いたしました!!
色々勉強になりました。
本当にありがとうございました。

またなにか分からないことがあったら、よろしくお願いします。

Blue 2005/05/18(水) 18:36:24
よくみたら
>>CString csDataFolder;
>>CString csPrefix;
>これらの変数(ローカル変数)の寿命は for分のスコープをでると終わります。

char chDataFolder[128];
char chPrefix[128];

のほうでしたね。orz

char* pchDataFolder = new char[ 128 ];
char* pchPrefix = new char[ 128 ];

等にして動的に確保したメモリに対してAddする場合は大丈夫です。
ですか、CArrayを使わなくなったときに動的に確保したメモリをdelete[]しなければな
りません。
CStringArrayはそこら辺の管理をしてくれているので便利であるというわけです。

古いスレッドには追加発言できません。