度々お世話になってます。
構造体を動的に確保し、処理後メモリーリークが起こらないように解放したいです。
item を m_xcList.GetItemCount() 個、宣言したいです。
ご教授願いたいです。
▼ソースの一部抜粋▼
void CFileListCreatorDlg::SameItemCheck(CString mySwitch)
{
LVITEM lvi;
int index = 0;
UpdateData();
lvi.mask = LVIF_TEXT;
CString FullPathString;
CString myFileName;
index = 0;
while (index < CFileListCreatorDlg::m_xcList.GetItemCount()){
lvi.iItem = index;
lvi.iSubItem = 0;
lvi.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(_T("")));
CFileListCreatorDlg::m_xcList.SetItem(&lvi);
index++;
}
//0:ファイル重複識別ナンバー 1:通し番号 2:フルパス 3:ファイル名 4:おおよそのデータサイズ 5:データサイズ 6:修正日 7:修正時間 8:備考欄 9:書式情報
//ファイル名、ファイル容量、修正日時により、重複チェック
struct item
{
CString RepetitionNum; //ファイル重複識別ナンバー
//int Num; //通し番号
CString FullPath; //ファイルパス
CString FileName; //ファイル名
//CString ApproximateByte; //おおよそのデータサイズ//バイト
CString AccurateByte; //実際のデータサイズ//実バイト
//TCHAR ModifyDate[20]; //修正日
//CTime ModifyTime; //修正時間
CString ModifyTime; //修正時間
//TCHAR RemarksColumn[100]; //備考欄
};
//http://www-watt.mech.eng.osaka-u.ac.jp/~tasai/cp … ← プログラム5を参考にしました。
struct item *array;
/* メモリの確保 */
array = (struct item*)malloc(sizeof(struct item)*(CFileListCreatorDlg::m_xcList.GetItemCount()-1));
if (array == NULL) {
StatusStringSet(_T("memory allocation error\r\n"),0,TRUE);
exit(EXIT_FAILURE);
}
//const int itemNum = sizeof item /sizeof array[0];
int i;
for (i = 0; i < CFileListCreatorDlg::m_xcList.GetItemCount(); i++) //初期化
{
array[i].RepetitionNum = _T(""); //ファイル重複識別ナンバー
array[i].FileName = _T(""); //ファイル名
array[i].AccurateByte = _T(""); //データサイズ
array[i].ModifyTime = _T(""); //修正時間
}
int cc;
int dd;
cc = 1;
dd = 1;
if(mySwitch == _T("SameItemCheck_BY_FileName")){
//0:ファイル重複識別ナンバー 1:通し番号 2:フルパス 3:ファイル名 4:おおよそのデータサイズ 5:データサイズ 6:修正日 7:修正時間 8:備考欄 9:書式情報
StatusStringSet(_T("ファイル名により、重複チェック"),0,FALSE);
index = 0;
while (index < CFileListCreatorDlg::m_xcList.GetItemCount()){
array[index].RepetitionNum = _T("");
FullPathString = CFileListCreatorDlg::m_xcList.GetItemText(index,2);
if(FullPathString != _T("")){
array[index].FileName = FullPathToFileName(FullPathString);
}
for (dd = 0; dd <= index-1; dd++){
if (array[dd].FileName == array[index].FileName){
if (array[index].RepetitionNum != _T("")){
array[dd].RepetitionNum = array[index].RepetitionNum;
//" 重複番号欄に既に重複Noが、入っているとき"
}else{
//cc // " インクリメントcc"
CString str;
if (cc>=INT_MAX){
str = _T("MAX-Value");
}else{
str.Format(_T("%d"),cc);
}
array[index].RepetitionNum = const_cast<LPTSTR>(static_cast<LPCTSTR>(str));
if (array[dd].RepetitionNum != array[index].RepetitionNum){
cc++;
}
}
lvi.iItem = index;
lvi.iSubItem = 0;
lvi.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(array[index].RepetitionNum));
CFileListCreatorDlg::m_xcList.SetItem(&lvi);
UpdateData(FALSE);
lvi.iItem = dd;
lvi.iSubItem = 0;
lvi.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(array[index].RepetitionNum));
CFileListCreatorDlg::m_xcList.SetItem(&lvi);
UpdateData(FALSE);
}
}
index++;
UpdateData(FALSE);
}
}else if(mySwitch == _T("SameItemCheck_By_DataSize")){
//省略
}
}
▲ソースの一部抜粋▲
コンパイルは通るのですが、実行時に↓のエラーがでます。
どこの部分ががおかしいのでしょうか??
▼エラーメッセージ▼
FileListCreator.exe の 0x00f08ac1 でハンドルされていない例外が発生しました: 0xC0000005: 場所 0xcdcdcdbd を読み込み中にアクセス違反が発生しました。
void Empty() throw()
{
CStringData* pOldData = GetData();
IAtlStringMgr* pStringMgr = pOldData->pStringMgr;
if( pOldData->nDataLength == 0 )
{
return;
}
if( pOldData->IsLocked() )
{
// Don't reallocate a locked buffer that's shrinking
SetLength( 0 );
}
else
{
pOldData->Release();
CStringData* pNewData = pStringMgr->GetNilString();
Attach( pNewData );
}
}
▲エラーメッセージ▲
汎用的なコードをお教え願いたいです。宜しくお願いします。
No.4ベストアンサー
- 回答日時:
#include <stdio.h>
int main()
{
int a[5];
for (i=1; i<=5; ++i)
a[i] = i*i;
for (i=1; i<=5; ++i)
printf("a[%d]=%d\n", i, a[i]);
return 0;
}
というプログラムは間違っています. どこが間違いかわかりますか?
この回答への補足
遅くなりました。
【誤】i<=5
【正】i<5
new とか、配列の宣言方法に目を囚われて、すみません。添え字の問題でしたか。
今、動作確認をしました。大丈夫そうです。
同様に、自プログラムの初期化部分と処理部分の終了条件を一つ少なくして、表記をそろえました。
【誤】i <= CFileListCreatorDlg::m_xcList.GetItemCount()
【正】i < CFileListCreatorDlg::m_xcList.GetItemCount()
void CFileListCreatorDlg::SameItemCheck(CString mySwitch)
{
▼初期化▼
int i;
for (i = 0; i < CFileListCreatorDlg::m_xcList.GetItemCount(); i++) //初期化
{
item[i].RepetitionNum = _T(""); //ファイル重複識別ナンバー
item[i].FileName = _T(""); //ファイル名
item[i].AccurateByte = _T(""); //データサイズ
item[i].ModifyTime = _T(""); //修正時間
}
▲初期化▲
▼重複ファイルチェック部分▼
cc = 1;
if(mySwitch == _T("SameItemCheck_BY_FileName")){
//m_xcListのコラムの添え字↓
//0:ファイル重複識別ナンバー 1:通し番号 2:フルパス 3:ファイル名 4:おおよそのデータサイズ 5:データサイズ 6:修正日 7:修正時間 8:備考欄 9:書式情報
//ファイル名により、重複チェック
index = 0;
while (index < CFileListCreatorDlg::m_xcList.GetItemCount()){
FullPathString = CFileListCreatorDlg::m_xcList.GetItemText(index,2);
if(FullPathString != _T("")){
item[index].FileName = FullPathToFileName(FullPathString); //ファイル名を取得するユーザー関数
}
for (dd = 0; dd < index; dd++){
if (item[dd].FileName == item[index].FileName){
if (item[index].RepetitionNum != _T("")){
item[dd].RepetitionNum = item[index].RepetitionNum;
//" 重複番号欄に既に重複Noが、入っているとき"
}else{
//cc // " インクリメントcc"
CString str;
if (cc>=INT_MAX){
str = _T("MAX-Value");
}else{
str.Format(_T("%d"),cc);
}
item[index].RepetitionNum = const_cast<LPTSTR>(static_cast<LPCTSTR>(str));
if (item[dd].RepetitionNum != item[index].RepetitionNum){
cc++;
}
}
lvi.iItem = index;
lvi.iSubItem = 0;
lvi.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(item[index].RepetitionNum));
CFileListCreatorDlg::m_xcList.SetItem(&lvi);
UpdateData(FALSE);
lvi.iItem = dd;
lvi.iSubItem = 0;
lvi.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(item[index].RepetitionNum)); // item[dd] ではなく item[index]の重複ナンバーを代入
CFileListCreatorDlg::m_xcList.SetItem(&lvi);
UpdateData(FALSE);
}
}
index++;
}
▲重複ファイルチェック部分▲
delete [] item;
} //SameItemCheck 終端
これでも、最初の目的であるメモリーリークが防げないようでしたら、お教え下さい。
明日あたりに、締め切ります。ありがとうございました。
肝心の宣言部が抜けていました。お礼欄にて失礼いたします。
struct itemStruct
{
CString RepetitionNum; //ファイル重複識別ナンバー
CString FullPath; //ファイルパス
CString FileName; //ファイル名
CString AccurateByte; //実際のデータサイズ//実バイト
CString ModifyTime; //修正時間
};
itemStruct *item;
item = new itemStruct[CFileListCreatorDlg::m_xcList.GetItemCount()];
それと、一応、処理部の外でもリストコントールの重複ナンバー欄を初期化しています。
冗長かもしれませんが。
LVITEM lvi;
int index = 0;
UpdateData();
lvi.mask = LVIF_TEXT;
CString FullPathString;
index = 0;
while (index < CFileListCreatorDlg::m_xcList.GetItemCount()){
lvi.iItem = index;
lvi.iSubItem = 0; //重複ナンバーが入るコラム
lvi.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(_T("")));
CFileListCreatorDlg::m_xcList.SetItem(&lvi);
index++;
}
以上です。
No.3
- 回答日時:
あとついでですが C でキャストしなくていいというのは 20年以上昔からそうですし, C++ なら std::vector 使えば
いいような.この回答への補足
アドバイスありがとうございます。
でも、今回のところは、new/deleteを採用したいです。
今のところ、↓ですが、どこが悪いのか分かりません。。。
{
struct itemStruct
{
CString RepetitionNum; //ファイル重複識別ナンバー
CString FullPath; //ファイルパス
CString FileName; //ファイル名
CString AccurateByte; //実際のデータサイズ//実バイト
CString ModifyTime; //修正時間
//} item[] =
// {_T(""),_T(""),_T(""),_T(""),_T(""),
};
itemStruct *item;
item = new itemStruct[CFileListCreatorDlg::m_xcList.GetItemCount()];
int i;
for (i = 1; i <= CFileListCreatorDlg::m_xcList.GetItemCount(); i++) //初期化
{
item[i].RepetitionNum = _T(""); //ファイル重複識別ナンバー
item[i].FileName = _T(""); //ファイル名
item[i].AccurateByte = _T(""); //データサイズ
item[i].ModifyTime = _T(""); //修正時間
}
~処理~
delete [] item;
}
以上、プログラム抜粋は、実行時エラーで、
void Empty() throw()
{
CStringData* pOldData = GetData();
IAtlStringMgr* pStringMgr = pOldData->pStringMgr; //←ここで止まってしまいます。
if( pOldData->nDataLength == 0 )
{
return;
}
if( pOldData->IsLocked() )
{
// Don't reallocate a locked buffer that's shrinking
SetLength( 0 );
}
else
{
pOldData->Release();
CStringData* pNewData = pStringMgr->GetNilString();
Attach( pNewData );
}
}
どうかお教え下さい。
No.1
- 回答日時:
他にもあるかもしれませんが、とりあえず
> array = (struct item*)malloc(sizeof(struct item)*(CFileListCreatorDlg::m_xcList.GetItemCount()-1));
これでstruct itemが何個分、確保できたと思いますか?
> for (i = 0; i < CFileListCreatorDlg::m_xcList.GetItemCount(); i++) //初期化
これで、何個分、struct itemを使うと思いますか?
それから、mallocに対してのfreeが無いようです。省略したところにあるかもしれませんが。
あとは、C++として使ってますよね?いろいろCには無い機能とか使われてますし。
それなら、malloc/freeよりはnew/delete を使った方がいいと思います。
まず、sizeofを使った計算も、ポインタのキャストも必要ありません。(最近のCならvoid*からキャストする必要は無いですが、C++だと必要)
コンストラクタ/デストラクタを丁寧に書いて、メンバの領域確保/解放を確実にするのもメモリリーク対策の一つですが、malloc/freeではコンストラクタ/デストラクタは呼ばれません。
この回答への補足
さっそくのご回答ありがとうございます。お礼が遅くなってすみません。
> > array = (struct item*)malloc(sizeof(struct item)*(CFileListCreatorDlg::m_xcList.GetItemCount()-1));
> これでstruct itemが何個分、確保できたと思いますか?
構造体を使うのは初めてで、何で型変換やサイズを取るのか、理解はしてませんが、
間違っているのですね。。。リストの行数分 - 1ですね。
でも他が悪いのか、試してみましたが、駄目でした。
> > for (i = 0; i < CFileListCreatorDlg::m_xcList.GetItemCount(); i++) //初期化
> これで、何個分、struct itemを使うと思いますか?
これは行数分使うと思います。
> それから、mallocに対してのfreeが無いようです。省略したところにあるかもしれませんが。
すみません、投稿するときに削ってしまいましたm(_ _)m
> それなら、malloc/freeよりはnew/delete を使った方がいいと思います。
> まず、sizeofを使った計算も、ポインタのキャストも必要ありません。(最近のCならvoid*からキャストする必要は無いですが、C++だと必要)
> コンストラクタ/デストラクタを丁寧に書いて、メンバの領域確保/解放を確実にするのもメモリリーク対策の一つですが、malloc/freeではコンストラクタ/デストラクタは呼ばれません。
調べてみました、確かにnew/deleteの方が良いようですね。ありがとうございます。
でも、malloc/freeを使った例も知りたいですが…
new/deleteで試みてますが、苦戦中です。
new の宣言部がわかりません・・・
◆開発環境
色々と環境や言語を書いてなくてすみません。
VC++2010、MFC、ユニコードを使用する設定になっています。
XP~7に対応させたいです。関係あるかは分かりませんが、スタティックリンク・マルチスレッドの設定です。
目的の機能ができました。malloc/free にしようとしていましたが、new/delete を教えていただきありがとうございます。
Vistaや7では、ちゃんと描画されるのに、XPでは描画されなかったので、
RedrawWindow(); //追加2011.12.10 //XP対策:再描画
をユーザー関数の最後にいれました。
それでは、またお世話になるかもしれませんが、そのときは宜しくお願いいたします。
(締め切ります。ポイントを差し上げられなくてごめんなさい。)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) サブフォルダ(データ)にある複数の.xlsxファイルのSheet3のA2セルの値で01から左側をB2 2 2022/08/14 15:46
- JavaScript 画像の表示位置 3 2022/12/23 08:25
- Visual Basic(VBA) 集めたシートのシート名を変更したい。 下記のコードでサブフォルダにあるファイルのSheet3を集めて 6 2022/08/23 10:38
- PHP imageフォルダに、画像をリサイズして保存する時のファイル名を変更したい 1 2023/05/30 11:39
- Visual Basic(VBA) エクセルのマクロについて教えてください。 2 2023/03/08 09:08
- Visual Basic(VBA) エクセルのマクロについて教えてください。 2 2023/03/12 10:10
- C言語・C++・C# c言語の問題です 課題1 (二分探索木とセット) 大きさ size の配列 array を考える。す 2 2023/01/10 21:08
- Ruby pandasでsqlite3にテーブル作成・追加・読み出しでindexの取り扱い方教えてください 5 2023/03/08 09:57
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- Excel(エクセル) ワードのマクロについて教えてください。 1 2023/03/11 13:50
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語 最大値と最小値を求めて...
-
行列
-
PHPで10連ガチャを作成したいの...
-
SESSION変数の2次元配列
-
Resource id #3 と表示されま...
-
変数に関して
-
プルダウンメニューにDBの内容...
-
multiple属性のPOSTを配列で受...
-
チェックボックス複数選択 mys...
-
$_SESSIONに二次元配列を使える...
-
VC++の構造体について。
-
pdfファイルの複数添付 引数の型
-
php Undefined variableエラー
-
CSVファイルの最終行のデー...
-
file_existsでファイル名の部分...
-
■PHPの初歩的なことについて・・・
-
CSVデータの行数カウントをした...
-
多次元配列のカウント+1の仕方
-
3次元配列を2次元配列にする方...
-
タブ区切りのデータでnullのデ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語の配列をPush(追加)する...
-
行列
-
np.stack()とnp.array()の違い
-
2次元配列CSVのソート
-
配列の要素(value)に、変数を...
-
C言語 最大値と最小値を求めて...
-
STLのvectorで作った配列をメン...
-
特定の文からメールアドレスの...
-
CArrayのソート
-
MYSQLとPHPによって取得する多...
-
ファイルの書き込みについて教...
-
CArrayの要素としてCStringArra...
-
verilogで、配列の一部をタスク...
-
array_intersectで空欄を比較し...
-
pg_copy_fromの使い方について...
-
cakephpでのトランザクション処...
-
同一列内のセルを結合して表示...
-
構造体を動的に確保&解放
-
c言語 単位行列
-
読み(あ行~わ行)ごとに分け...
おすすめ情報