CRecordsetクラスのdelete時のヒープエラー – プログラミング – Home

通知
すべてクリア

[解決済] CRecordsetクラスのdelete時のヒープエラー

固定ページ 1 / 2

おみおみ
 おみおみ
(@おみおみ)
ゲスト
結合: 20年前
投稿: 20
Topic starter  

.net 2003 MFC使用。

CRecordsetを派生したクラスCRsHaseiをDLLで定義し、
Exe側ではそのクラスを以下のように使用

CRsHasei* pRs = new CRsHasei;
pRs ->Open();
pRs ->Close();

delete pRs;//ここでヒープエラー

DLLを使用しない場合はエラーになりません。
また、下記のようにオープン、クローズなしだとエラーになりません。

CRsHasei* pRs = new CRsHasei;
delete pRs;

原因や対応がわかりません。
よろしくお願い致します。


引用未解決
トピックタグ
ITO
 ITO
(@ITO)
ゲスト
結合: 23年前
投稿: 1235
 

原因は、「delete pRs;」を行うタイミングで pRsを使っているので例外が 
    発生したんだと思います。
>CRsHasei* pRs = new CRsHasei;
DLL側で行う必要ありますか?
アプリケーション側なら、
「InitInstance()」でnewしてExitInstance()でdeleteすれば済みます。
DLLだとどこでどのタイミングで「CRsHasei」を使うか分りません。
  


返信引用
おみおみ
 おみおみ
(@おみおみ)
ゲスト
結合: 20年前
投稿: 20
Topic starter  

すみません。ちょっと意味が理解できていないので、
ずれた返信かもしれませんが、
下記の処理は全てアプリケーション側で実行しています。

CRsHasei* pRs = new CRsHasei;
pRs ->Open();
pRs ->Close();
delete pRs;//ここでヒープエラー

>DLL側で行う必要ありますか?
これは上記の処理のことですか?CRsHaseiの定義のことですか?

>アプリケーション側なら、
>「InitInstance()」でnewしてExitInstance()でdeleteすれば済みます。

deleteはCRsHaseiを利用するクラスのデストラクタで実行したいと思っています。

よろしくお願いします。


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

>これは上記の処理のことですか?CRsHaseiの定義のことですか?
>CRsHasei* pRs = new CRsHasei;
>delete pRs;//ここでヒープエラー
この二つの文のことです。
>deleteはCRsHaseiを利用するクラスのデストラクタで実行したいと思っています。
今でもそうしていますか?
-----ココカラ------
pRs ->Open();
--処理---
pRs ->Close();
-----ココマデ---------
の処理にスレッドを使用していて、deleteする時に終わっていないとまずいですね。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

単純に派生したクラスの実装に問題があってメモリの状態がおかしくなっているとかあり
えないですか?
何らかの処理をするとおかしくなるのであれば、ありえないこともなさそうな気がします
けれど。
実際の実装がどうなっているのかわからないので単なる想像ですけれど。


返信引用
おみおみ
 おみおみ
(@おみおみ)
ゲスト
結合: 20年前
投稿: 20
Topic starter  

>CRsHasei* pRs = new CRsHasei;
>delete pRs;

上記はExe側で実行しています。

>deleteはCRsHaseiを利用するクラスのデストラクタで実行したいと思っています。
今でもそうしていますか?

はい。それにテストとして、通常の関数内でも試しています。

>-----ココカラ------
>pRs ->Open();
>--処理---
>pRs ->Close();
>-----ココマデ---------
>の処理にスレッドを使用していて、deleteする時に終わっていないとまずいですね。

そうなんでしょうか。DLLを使用しない場合はスレッドにしなくてもエラーになりませ
ん。

>単純に派生したクラスの実装に問題があってメモリの状態がおかしくなっているとかあ
>りえないですか?
>何らかの処理をするとおかしくなるのであれば、ありえないこともなさそうな気がしま
>すけれど。

処理をおっていったところ、メモリのアドレス(pRsの値)は変わっていませんでした。
テスト時はオープンとクローズの間に何もしていません。

ちなみにCRsHaseiを定義したDLL内ではdelete時にエラーになりません。


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

>そうなんでしょうか。DLLを使用しない場合はスレッドにしなくてもエラーになりませ
>ん。
すみません、文章がおかしかったです。


>の処理にスレッドを使用していて、deleteする時に終わっていないとまずいですね。


の処理にスレッドを使用していた場合、deleteする時に終わっていないと
まずいですね。       


返信引用
おみおみ
 おみおみ
(@おみおみ)
ゲスト
結合: 20年前
投稿: 20
Topic starter  

>の処理にスレッドを使用していた場合、deleteする時に終わっていないと
まずいですね。 

ああ、そういう意味ならそうですね。

ITOさんの最初の書き込みの意味も分かりましたが、多分そういう制限はないと思いま
す。DLLにしなければ問題ないですので。

DLLの作り方が悪いのかもしれません。
明日ソース載せますので、よろしくお願いします。


返信引用
おみおみ
 おみおみ
(@おみおみ)
ゲスト
結合: 20年前
投稿: 20
Topic starter  

>処理をおっていったところ、メモリのアドレス(pRsの値)は変わっていませんでした。

これは良く考えたら当たり前で、pRsの指す目盛りの中身を見ないとだめですね。

以下ソースです。

------------------------------------------------------
//RsWrapper.h
#pragma once
#include < afxdb.h >

class DLL_EXPORT_INEMS CRsWrapper : public CRecordset
//DLL_EXPORT_INEMSはマクロで、DLLでは__declspec(dllexport)、
//Exeでは__declspec(dllimport)になります。
{
public:
CRsWrapper( CString p_cStrFolderPath, CString p_cStrFileName, CString
p_cStrTableName, CDatabase* p_pdb = NULL );

CRsWrapper( CString p_cStrFilePath, CString p_cStrTableName,
Database* p_pdb = NULL );

CRsWrapper( CDatabase* p_pdb = NULL );
virtual ~CRsWrapper();
DECLARE_DYNAMIC(CRsWrapper)

// オーバーライド
// ウィザードで生成された仮想関数のオーバーライド
public:
virtual CString GetDefaultConnect(); // 既定の接続文字列
virtual CString GetDefaultSQL(); // レコードセットの既定の SQL

virtual void vSetFolderPath( CString p_cStrFolderPath );
virtual void vSetFileName( CString p_cStrFileName );
virtual void vSetTableName( CString p_cStrTableName );
// 実装
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif

};


返信引用
おみおみ
 おみおみ
(@おみおみ)
ゲスト
結合: 20年前
投稿: 20
Topic starter  

//RsWrapper.cpp
#include stdafx.h
#include RsWrapper.h

IMPLEMENT_DYNAMIC( CRsWrapper, CRecordset )
CRsWrapper::CRsWrapper( CString p_cStrFolderPath, CString p_cStrFileName,
CString p_cStrTableName, CDatabase* p_pdb ): CRecordset( p_pdb )
{
vSetFolderPath( p_cStrFolderPath );
vSetFileName( p_cStrFileName );
vSetTableName( p_cStrTableName );
}

CRsWrapper::CRsWrapper( CString p_cStrFilePath, CString p_cStrTableName,
CDatabase* p_pdb ): CRecordset( p_pdb )
{
vSetFolderPath( CDevCommon::cStrAbstFolderPath( p_cStrFilePath ));
vSetFileName( CDevCommon::cStrAbstFileName( p_cStrFilePath ));
vSetTableName( p_cStrTableName );
}

CRsWrapper::CRsWrapper( CDatabase* p_pdb ) : CRecordset( p_pdb )
{
}

CRsWrapper::~CRsWrapper()
{
}

CString CRsWrapper::GetDefaultConnect()
{
return _T (ODBC;DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS
Access};DBQ=) + m_cStrFolderPath + \\ + m_cStrFileName;
}

CString CRsWrapper::GetDefaultSQL()
{
return _T([) + m_cStrTableName + _T(]);
}

void CRsWrapper::vSetFolderPath( CString p_cStrFolderPath )
{
m_cStrFolderPath = p_cStrFolderPath;
}

void CRsWrapper::vSetFileName( CString p_cStrFileName )
{
m_cStrFileName = p_cStrFileName;
}

void CRsWrapper::vSetTableName( CString p_cStrTableName )
{
m_cStrTableName = p_cStrTableName;
}
/////////////////////////////////////////////////////////////////////////////
// CRsWrapper 診断

#ifdef _DEBUG
void CRsWrapper::AssertValid() const
{
CRecordset::AssertValid();
}

void CRsWrapper::Dump(CDumpContext& dc) const
{
CRecordset::Dump(dc);
}
#endif //_DEBUG


返信引用
おみおみ
 おみおみ
(@おみおみ)
ゲスト
結合: 20年前
投稿: 20
Topic starter  

気づいたのです、今までの例は若干実際とは違っていました。
実際は以下のとおりです。

CRsWrapper・・・DLLで定義
CRsHasei・・・Exeで定義

↓Exeで使用
CRsHasei* pRs = new CRsHasei;
pRs ->Open();
pRs ->Close();
delete pRs;//ここでヒープエラー


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

実際は、「CRsHasei」のクラスが、DLLn関数を動かしているのですね。
ところで、
>CRsHasei* pRs = new CRsHasei;
何のために必要なんですか?
普通に
CRsHasei* pRs = new CRsHasei;
では駄目ですか?


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

CRsHasei がアプリケーション上で動いている以上
わざわざ、newする必要がないと思います。
ヒープに移すほどの容量のメモリーを使っているのでしょうか?


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

普通にと言うのはこういうことですよね、多分。

CRsHasei Rs;


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

PATIOさん、フォロー有難う御座います。
>CRsHasei Rs;
すみません、間違っていました。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

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