ページ 1 / 1
free関数使用時に発生するエラー
Posted: 2006年7月13日(木) 20:55
by ganas
こんにちは。
今回、動的配列の作り方などを、以前使っていたC++から、見よう見まねで作り、そして、以下のようなコードとなりました。
これは、リリースコンパイルしたものには何の問題もありません(正確には目に見える動きがない)。しかし、デバッグ実行では、「HEAP[vtroad_debug.exe]: Invalid Address specified to RtlFreeHeap( 00140000, 0040B0FC )
」というエラーメッセージがでて、停止してしまいます。
最終的に、callocやrecalloc、freeを用いて、動的配列を簡単に定義できる関数を作る予定なのですが、この問題はどのように対処したらよいでしょうか。
また、この方法(callocで配列定義)でString型の代用は可能でしょうか。
Posted: 2006年7月13日(木) 21:22
by Ryo
http://www.activebasic.com/help_center/ ... index.html
上記講座に書かれているように、Byte配列では a="う" でなく、 lstrcpy()関数を使用します。
a = "う" を lstrcpy (a,"う") と変更してみてください。
Posted: 2006年7月13日(木) 21:25
by イグトランス
> a = "う"
これが良くないです。
これによって,aはcallocで確保したメモリではなく,"う"を指すことになるのでfreeでエラーになってしまうのです。
正しくはlstrcpy(a, "う")などとします。C++(というよりC)と変わりません。
ただstrcpyが無いのでWinAPIのlstrcpyを使っているだけです。
また、String型を使うとこうなります。
メモリ確保にはZeroString,解放は自動で行われると考えればよいです。
ただしZeroStringは文字列終端の\0文字の分,引数より1バイト多くメモリ確保します。
StrPtrはString型の変数から文字列の先頭を指すポインタ (*Byte)を返す関数です。
コード: 全て選択
Dim a As String
a = ZeroString(sizeof(Byte) * 255)
lstrcpy(StrPtr(a), "う")
Msgbox hMainWnd, a
ただし,この状態ではaにLen関数を使用したときに255を返し,文字列連結などが正常に行えない(ように見える)ことになるはずです。
きちんと処理するにはString型文字列の長さを保持している部分を書き換えてやる必要があります。それは現在のところこんな感じになります。
コード: 全て選択
SetDWord(StrPtr(a) - SizeOf (DWord), lstrlen(StrPtr(a)))
Posted: 2006年7月14日(金) 15:16
by ganas
ありがとうございます。
参考にしてみます。
Posted: 2006年7月14日(金) 18:28
by ganas
・・・とりあえず、文字列クラスを作ってみました。
簡単なプログラムの場合は普通に動きますが、複雑なプログラム(SetTextを1回、GetTextを複数)の場合、デストラクタでエラー(HEAP[vtroad_debug.exe]: Heap block at 0017AA58 modified at 0017AC12 past requested size of 1b2
)を出すときがありますが、それなりに形になりました。
コード: 全て選択
'文字列クラス
Class CText
Private
ctStr As BytePtr
Public
'コンストラクタ
Sub CText()
ctStr = calloc(sizeof(BytePtr) * 256) As BytePtr
If ctStr = NULL Then
MessageBox(NULL,"エラー! メモリ確保に失敗しました。" + Chr$(13) + Chr$(10) + Chr$(13) + Chr$(10) + "ご迷惑をおかけしますが、プログラムは強制終了されます。","CText コンストラクタ",MB_ICONSTOP)
free(ctStr)
End
End If
End Sub
'デストラクタ
Sub ~CText()
free(ctStr)
End Sub
'文字列を代入する
Sub SetText(text As BytePtr)
free(ctStr)
ctStr = calloc(lstrlen(text)) As BytePtr
If ctStr = NULL Then
MessageBox(NULL,"エラー! メモリ確保に失敗しました。" + Chr$(13) + Chr$(10) + Chr$(13) + Chr$(10) + "ご迷惑をおかけしますが、プログラムは強制終了されます。","CText コンストラクタ",MB_ICONSTOP)
free(ctStr)
End
End If
lstrcpy(ctStr,text)
End Sub
'文字列を取得する
Function GetText() As BytePtr
GetText = ctStr
End Function
End Class