CArrayのGetAt()を使うとアサートが発生してしまいます。 – プログラミング – Home

CArrayのGetAt()を使うとア...
 
通知
すべてクリア

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


にゃも
 にゃも
(@にゃも)
ゲスト
結合: 20年前
投稿: 7
Topic starter  

こんにちわ。
にゃもといいます。

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()をコメントアウトすると、アサートは発生しません。

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

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


引用未解決
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

> str = m_caOfFolder.GetAt(1);

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


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

この後で、free(str)としていませんか?


返信引用
にゃも
 にゃも
(@にゃも)
ゲスト
結合: 20年前
投稿: 7
Topic starter  

早速のお返事ありがとうございます。

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

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

よろしくお願いします。


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

caOfFolderへ要素を追加した後に、その文字列データを破棄していませんか?
caOfFolderは文字列へのポインタを保持するだけで、文字列の内容は保持しません。

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

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


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

> CArray<LPSTR,LPSTR> m_caOfFolder;
CStringArrayを使わないのは何か問題があるのでしょうか?
結局mallocするならばそっちのほうがベターだと思うのですが。


返信引用
にゃも
 にゃも
(@にゃも)
ゲスト
結合: 20年前
投稿: 7
Topic starter  

strcpyを使ってみましたが、だめでした・・・。
何か、もっと別なところが原因のような気もします。

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


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

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

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


返信引用
にゃも
 にゃも
(@にゃも)
ゲスト
結合: 20年前
投稿: 7
Topic starter  

要素を追加しているソースは

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
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

>CString csDataFolder;
>CString csPrefix;
これらの変数(ローカル変数)の寿命は for分のスコープをでると終わります。

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

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


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

>>caOfFolderへ要素を追加した後に、その文字列データを破棄していませんか?

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

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

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


返信引用
にゃも
 にゃも
(@にゃも)
ゲスト
結合: 20年前
投稿: 7
Topic starter  

REEさん、Blueさん、ありがとうございます!
教えていただいたように変更してみたら、
いとも簡単に解決いたしました!!
色々勉強になりました。
本当にありがとうございました。

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


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

よくみたら
>>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はそこら辺の管理をしてくれているので便利であるというわけです。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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