ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2024年3月28日(木) 23:46

全ての表示時間は UTC+09:00 です




新しいトピックを投稿する  トピックへ返信する  [ 9 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2008年8月07日(木) 17:06 
waveoutをつかった音合成のプログラムを作っているのですが
debugするとメモリ解放時に
HEAP[wavelast_debug.exe]: Heap block at 00191D30 modified at 0019C97C past requested size of ac44
スレッド(&HDE0)のブレーク ポイント(EPI=&H77F75554)。
HEAP[wavelast_debug.exe]: Invalid Address specified to RtlFreeHeap( 00140000, 00191D38 )
スレッド(&HDE0)のブレーク ポイント(EPI=&H77F75554)。
というエラーが出ます。これってメモリのエラーですよね?
(経験上そう思う)

ところが実際にコンパイルしてみると正常に動作します。
しかしエラーが出る以上はやはり問題があると思います。
メモリ上のエラーは致命的なので何とかしたいです。

実はメモリやwaveoutはあまり知らないので
勉強しながらやっている状態です。
ソースをさらしたいのですが超ロングぐだぐだクソースなため
見せるに忍びないので重要そうな部分をさらします。

メモリ確保から演奏開始まで
コード:
ZeroMemory(VarPtr(pwh),sizeof(WAVEHDR))
pwh.lpData=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,SRATE)'SRATEは曲の長さ
For i=0 TO SRATE
    pwh.lpData(i)=(i番目のデータ)←省略している
Next
pwh.dwBufferLength=SRATE
pwh.dwFlags=WHDR_BEGINLOOP or WHDR_ENDLOOP
pwh.dwLoops=1
waveOutPrepareHeader(hwo,pwh,sizeof(WAVEHDR))
waveOutWrite(hwo,pwh,sizeof(WAVEHDR))

で問題となる終了時はコールバックにて
コード:
Function MainWndProc(hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord) As DWord
	' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
	Select Case dwMsg
      case MM_WOM_DONE
        waveOutUnprepareHeader(hWaveOut,pwh,sizeof(WAVEHDR))
        HeapFree(GetProcessHeap(),0,pwh.lpData)←ここでエラーが出る
waveoutではwaveOutUnprepareHeaderとHeapFreeは
プログラム終了時だけではなく、演奏終了時にやらないと
メモリ使用量が上昇してしまうので抜け目なくやっているつもりです。
実際メモリ使用量も上がったり下がったりで困っています。

・・・どうでも良いですが実はVer2.0辺りからABをやっていて
掲示板にもちょくちょく顔を出していたのですが、いつの間にか行かなくなり
ABもVer3.0~4.0初期しか使用しておらず、最近来て見たら
Ver5.0とかの話になってて時代の流れを感じました。


通報する
ページトップ
   
投稿記事Posted: 2008年8月07日(木) 21:50 
オフライン

登録日時: 2005年5月31日(火) 07:49
記事: 162
引用:
HEAP[wavelast_debug.exe]: Heap block at 00191D30 modified at 0019C97C past requested size of ac44
スレッド(&HDE0)のブレーク ポイント(EPI=&H77F75554)。
HEAP[wavelast_debug.exe]: Invalid Address specified to RtlFreeHeap( 00140000, 00191D38 )
スレッド(&HDE0)のブレーク ポイント(EPI=&H77F75554)。
この警告メッセージは、HeapAlloc() で確保した領域の外にまで値を書き込んでしまったときのものです。
プログラムが debug 版なら、メモリ解放時に領域周辺が汚されていないかチェックして、もし汚れていたらこのような警告を吐いてブレークします。

この手のバグは見つけ出すのが難しいことも多いですが・・・
とりあえず、その領域に書き込むコードを重点的に調べてみてください。
たとえば、書き込む前にそのポインタが正しく領域内を指しているか逐一チェックするなど。

# そういえば Assert ってないんですかね。


通報する
ページトップ
投稿記事Posted: 2008年8月09日(土) 13:04 
返信ありがとうございます。
いろいろやっていたので返事が遅れてしまってすいません。
書き込み時に間違いがある、とのことでしたので、
書き込みの部分を調べてみました。
といっても書き込みを行う部分は前回投稿した部分のみなので
その辺で試したのですが、
コード:
ZeroMemory(VarPtr(pwh),sizeof(WAVEHDR)) 
pwh.lpData=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,SRATE)'SRATEは曲の長さ 
’ここをAとして
For i=0 TO SRATE 
    pwh.lpData(i)=(i番目のデータ)←省略している 
Next 
’ここをBとする。
pwh.dwBufferLength=SRATE 
pwh.dwFlags=WHDR_BEGINLOOP or WHDR_ENDLOOP 
pwh.dwLoops=1 
waveOutPrepareHeader(hwo,pwh,sizeof(WAVEHDR)) 
waveOutWrite(hwo,pwh,sizeof(WAVEHDR)) 
 
上のコードでAの部分でメモリの解放を行ったところ問題はなく、
Bで解放したところ例のエラーが出ました。
つまり書き込みのこの部分に問題があったとわかりました。
コード:
For i=0 TO SRATE 
    pwh.lpData(i)=(i番目のデータ)←省略している 
Next 
 
そうなると怪しいのが省略してしまった部分なのですが、よく見ると
型を間違えてました(オイ)。ポインタと値がごっちゃになってましたので修復しました。
しかしどういうわけかこれでも改善がされません。
実際のところエラーが発生する回数は減ったのですが、
稀にエラーが出ています。
回数が少なくなったのは良いですがデバッグがしずらいです。
省略部分は音の合成の部分なのですがやはり省略した部分が
悪いのでしょうか?といってもソースを曝さなきゃわかりませんが
カオス過ぎて時間がかかりそうなのでとりあえず現状を報告しました。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2008年8月09日(土) 14:15 
オフライン

登録日時: 2005年7月25日(月) 13:27
記事: 893
お住まい: 埼玉県東松山市
コード:
For i=0 TO SRATE 
    pwh.lpData(i)=(i番目のデータ)←省略している 
Next 
コード:
For i=0 TO SRATE-1
    pwh.lpData(i)=(i番目のデータ)←省略している 
Next 
にしてみたらどうなりますか?

_________________
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。


通報する
ページトップ
投稿記事Posted: 2008年8月09日(土) 22:13 
ちょっとした改良なので即実行してみましたが
同様のエラーが出てしまいました。
似たような考えで確保する領域を増やす方法も考えたのですが
だめでした。
コード:
ZeroMemory(VarPtr(pwh),sizeof(WAVEHDR))
pwh.lpData=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,SRATE)'SRATEは曲の長さ
For i=0 TO SRATE-1
    pwh.lpData(i)=(i番目のデータ)←省略している
Next
pwh.dwBufferLength=SRATE
pwh.dwFlags=WHDR_BEGINLOOP or WHDR_ENDLOOP
pwh.dwLoops=1
waveOutPrepareHeader(hwo,pwh,sizeof(WAVEHDR))
waveOutWrite(hwo,pwh,sizeof(WAVEHDR))
それとやってて気づいたのですがwaveOutUnprepareHeaderのときにも
エラーが出るようです。こちらのエラーのほうが頻度が低いです。
コード:
Function MainWndProc(hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord) As DWord
    ' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
    Select Case dwMsg
      case MM_WOM_DONE
        waveOutUnprepareHeader(hWaveOut,pwh,sizeof(WAVEHDR)))←ここでもエラーが出る 
       HeapFree(GetProcessHeap(),0,pwh.lpData)←ここでエラーが出る 
でそのときのエラーメッセージは
「スレッド(&HAC8)でアクセス違反がありました(EPI=&H76AF1F22)。」
というような感じになっています。


通報する
ページトップ
   
 記事の件名: 書き忘れ
投稿記事Posted: 2008年8月09日(土) 23:19 
書き忘れましたが、
SRATE-1(もしくは確保領域を増やす)をするとエラー頻度は確実に減ります。
しかし100%ではありません。
というかムリだったらもうこれでもいいかな、なんて思ってきました。


通報する
ページトップ
   
 記事の件名: 過去ログで気づいた
投稿記事Posted: 2008年8月09日(土) 23:47 
過去ログに似たようなものを発見したのですが
引用:
> ヒープ領域に対してメモリを確保(HeapAlloc,HeapReAlloc)した場合、
> 実は確保したメモリ以上にデータを扱う事ができます。
> これは確保されたヒープハンドルがハンドルに過ぎないためであり、
> たまたま未確保の領域を侵しても実害が無かっただけに過ぎません。
>
> しかし、幾ら実害が無くても確保したヒープ領域を開放(HeapFree)すると、
> 確保した領域外のデータまでクリアしてしまうみたいで
> 初めてエラーが発覚したりします。
>
> この辺はABというよりAPIの問題になってきますので、
> 一度MSDN等を参照されることをお勧めします。
>
> http://www.microsoft.com/japan/msdn/
とまけイヌさんが書いていました。(そういえばこの名を聞くのも久しぶりダ・・・)
takさんが言っていることと本質的には変わりないのですが、
なんか結構面倒そうになってきた。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2008年8月10日(日) 00:41 
オフライン

登録日時: 2005年7月25日(月) 13:27
記事: 893
お住まい: 埼玉県東松山市
試しに適当に作ってみたのですが、特にエラーは出ないようです。

_________________
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。


通報する
ページトップ
投稿記事Posted: 2008年8月10日(日) 13:22 
わざわざつくっていただいてすいません。
お手数お掛けしました。
ソースを(ざっと見て)比較してみたのですが
基本的には同じようです。
ほとんどがコピペのように一緒なのですが、
微妙に型が違っている部分が数箇所ありました。
そういえば作るときに勉強しながら大急ぎでつくったので
結構突貫工事だった気がします。
前回のミスといい、型が間違っていたようですね。(←もはや馬・・・)

それともう一点重要そうなのが、
いままでABのver3を使ったのですが、
konisiさんのソースをABver3で使うとエラーが沢山出ます。(これは当たり前として)
で、AB4用のものであると気づき実行してみると何の問題もなく出来ました。
連続演奏に対応するように書き換えたものも正常に動きました。
どうも旧バージョンに対する執着(?)が強かったのが原因のようです。
AB3でも型に気をつければ出来ると思ったのですが・・・。
ソースを手がかりに修正してみます。
わざわざありがとうございました。


通報する
ページトップ
   
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 9 件の記事 ] 

全ての表示時間は UTC+09:00 です


オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[25人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
cron
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by ocean