作成者 |
メッセージ |
|
|
たかせ様
ご回答ありがとうございます。
1Byte分多く確保すると、きちんと取得することができました!
ありがとうございました!!
また質問させていただくとは思いますが、
その時はよろしくお願い致します。
今回は本当にありがとうございました!
たかせ様
ご回答ありがとうございます。 1Byte分多く確保すると、きちんと取得することができました! ありがとうございました!!
また質問させていただくとは思いますが、 その時はよろしくお願い致します。 今回は本当にありがとうございました!
|
|
|
投稿記事 |
Posted: 2012年6月20日(水) 01:46 |
|
|
|
|
|
ソースコード大雑把に見ましたが確認したい点があります。
ReadByte=SearchOneTextPointFormFile(hFile,Ex"\n",StartPoint)を実行するとたとえばノード名が"NoDe01\r\n"のときReadByteに8が設定されますよね?
これは私の勝手な想像ですが、
ツリー名を格納するエリアが8バイト分初期化して確保されます。
TreeName=calloc(ReadByte)
そして8バイト分ファイルから読み込まれます。
If ReadFile(hFile,TreeName,ReadByte,VarPtr(ReadFileLen),ByVal 0)=FALSE Then
MessageBox(hMainWnd,Ex"ファイルの値が読み出せません\r\nError:TreeName","Error",MB_OK or MB_ICONWARNING)
free(NodeInfo)
free(TreeName)
Exit Do
End If
しかしこれでは文字列の終端を示すNULL文字(0)が設定されていません。
なので”いらぬ文字”が付加される可能性があると思います。
そこで
TreeName=calloc(ReadByte)を
TreeName=calloc(ReadByte + 1)に変えてみてはいかがでしょうか?
つまりNULL文字(0)の分1バイト多く確保します。
ちなみにmallocだと
TreeName=malloc(ReadByte + 1)
ReadFile(hFile,TreeName,ReadByte,VarPtr(ReadFileLen),ByVal 0)
TreeName(ReadByte)=0
となります。
念のためご確認願います。
よろしくお願いします。
ソースコード大雑把に見ましたが確認したい点があります。
ReadByte=SearchOneTextPointFormFile(hFile,Ex"\n",StartPoint)を実行するとたとえばノード名が"NoDe01\r\n"のときReadByteに8が設定されますよね?
これは私の勝手な想像ですが、 ツリー名を格納するエリアが8バイト分初期化して確保されます。 TreeName=calloc(ReadByte) そして8バイト分ファイルから読み込まれます。 If ReadFile(hFile,TreeName,ReadByte,VarPtr(ReadFileLen),ByVal 0)=FALSE Then MessageBox(hMainWnd,Ex"ファイルの値が読み出せません\r\nError:TreeName","Error",MB_OK or MB_ICONWARNING) free(NodeInfo) free(TreeName) Exit Do End If しかしこれでは文字列の終端を示すNULL文字(0)が設定されていません。 なので”いらぬ文字”が付加される可能性があると思います。 そこで TreeName=calloc(ReadByte)を TreeName=calloc(ReadByte + 1)に変えてみてはいかがでしょうか? つまりNULL文字(0)の分1バイト多く確保します。 ちなみにmallocだと TreeName=malloc(ReadByte + 1) ReadFile(hFile,TreeName,ReadByte,VarPtr(ReadFileLen),ByVal 0) TreeName(ReadByte)=0 となります。
念のためご確認願います。 よろしくお願いします。
|
|
|
投稿記事 |
Posted: 2012年6月18日(月) 19:44 |
|
|
|
|
|
kobo様
ご回答ありがとうございます。
私も独学なので、アホなことばかりしております><
引用: ②から Forで繰り返し処理をされているのかなと思いますが
③で開放したあと①でメモリ確保をしていますが
callocの説明に「malloc関数とは異なり、この関数ではメモリの0クリアを行います。」
とあり、mallocでは何かのデータが入っているかもしれないのが原因の1つではないかとおもったりしました。
①より 要るかいらないか分かりませんが文字列の最後は「0」で終わるようにしましょう的な事を
どっかで聞きかじっているので
buffer=malloc(lstrlen(TreeName) + Len(Ex"\n"))
↓
buffer=calloc(lstrlen(TreeName) + Len(Ex"\n") +1 )
のほうが安全ぽいなぁと思いました。
上の画像をご覧いただければ見えやすくなると思いますが、
ツリービューをもちいたテキストエディタで、内容をアーカイブ保存しようとしていますので、
Forループでノードの内容すべてを保存しようとしております。
mallocもcallocも試したのですが、同じだったのです……
あ!NULL文字!!
確かに+1がいるかも知れません。
後でABのテキスト見なおしてみます!!
とりあえず、いじり回って気がついたことと解決と疑問と続きの質問をば。
まず、私の
コード: buffer=malloc(lstrlen(TreeName) + Len(Ex"\n"))
lstrcat(buffer,TreeName)
lstrcat(buffer,Ex"\n")
ですが、連結かつ連結!となっています。
そりゃゴミつくわね……
コード: buffer=malloc(lstrlen(TreeName) + Len(Ex"\n"))
lstrcpy(buffer,TreeName)
lstrcat(buffer,Ex"\n")
とするのが正解でした。
しかし、確保しているメモリ以上に連結してエラーが出なかったのはちょっと困りましたね……
もしかして、
引用: ※たまに、Heap block at ○○ modified at ×× past requested size of △と出ます(メモリが足り無い?)
※たまに、Invalid address specified to RtlFreeHeap(○○,☓☓ )と出ます(変なところに書き込まれている?)
これがそのエラーだったのかな……?
とりあえず、これで、おそらく、ファイルの保存はできたと思います。
保存は出来ました。
しかし、デバグ時に必ず、
Heap block at ○○ modified at ×× past requested size of △
が連発します。
なので、size of △の△をmallocするときに加えました。
エラーは消えますが、もちろん値が変わった時(例:△=3だった時にmallocで3を加えた。今度は△=6だとエラーが出る)に、
同じエラーが出るので、ちょっと腹が立ち、*2にするとエラーも出ず、値もしっかりファイルに保存されました。
何故*2にしたら保存されるのかが謎です。
あと、malloc、calloc関数ですが、これは上書きされるのかなぁ……?
みたいな疑問も。
Dim a As *Byte
a=malloc(10)
lstrcpy(a,"test data")
a=calloc(11)
lstrcpy(a,"test dataA")
free(a)
のようなプログラムだと、どうなっているのかな……みたいな。
メモリAが確保されたまま、違うメモリBを確保し、メモリBだけ解放されてる……
となっているのでしょうか。
……そうならないためのreallocなのかなぁ
さて、再度質問させて頂きます。
書き込んだデータを読み込むと、先と同様、いらぬ文字が付加されます。
保存したデータ
↓
読み込んだデータ
ツリーのノードを読み込む処理は、以下の様な感じです。
コード: 'ツリー名を確認
ReadByte=SearchOneTextPointFormFile(hFile,Ex"\n",StartPoint)
If ReadByte=0 Then
Exit Do
End If
TreeName=calloc(ReadByte)
'ファイルポインタを動かす
SetFilePointer(hFile,StartPoint,0,FILE_BEGIN)
If ReadFile(hFile,TreeName,ReadByte,VarPtr(ReadFileLen),ByVal 0)=FALSE Then
MessageBox(hMainWnd,Ex"ファイルの値が読み出せません\r\nError:TreeName","Error",MB_OK or MB_ICONWARNING)
free(NodeInfo)
free(TreeName)
Exit Do
End If
'検索開始ポイントをずらす
StartPoint=StartPoint+ReadByte+1
SearchOneTextPointFormFile関数は以下のように定義しています。
コード: Function SearchOneTextPointFormFile(hFile As HFILE,Text As BytePtr,SearchStartPoint As Long) As Long
Dim temp[0] As Byte
Dim Count As Long
Dim ReadFileLen As DWord
Dim SearchPointLog As Long
'ファイルのポインタの位置を記録
SearchPointLog=SearchStartPoint
'ポインタを動かす
SetFilePointer(hFile,SearchStartPoint,0,FILE_BEGIN)
Do
If ReadFile(hFile,temp,1,VarPtr(ReadFileLen),ByVal 0)=FALSE or ReadFileLen=0 Then
Exit Do
End If
If lstrcmp(temp,Text)=0 Then
SearchOneTextPointFormFile=Count
'ポインタを戻す
SetFilePointer(hFile,SearchPointLog,0,FILE_BEGIN)
Exit Function
End If
Count++
Loop
SearchOneTextPointFormFile=0
'ポインタを戻す
SetFilePointer(hFile,SearchPointLog,0,FILE_BEGIN)
End Function
よろしくお願いいたします。
kobo様 ご回答ありがとうございます。 私も独学なので、アホなことばかりしております><
[quote]②から Forで繰り返し処理をされているのかなと思いますが ③で開放したあと①でメモリ確保をしていますが callocの説明に「malloc関数とは異なり、この関数ではメモリの0クリアを行います。」 とあり、mallocでは何かのデータが入っているかもしれないのが原因の1つではないかとおもったりしました。 ①より 要るかいらないか分かりませんが文字列の最後は「0」で終わるようにしましょう的な事を どっかで聞きかじっているので buffer=malloc(lstrlen(TreeName) + Len(Ex"\n")) ↓ buffer=calloc(lstrlen(TreeName) + Len(Ex"\n") +1 ) のほうが安全ぽいなぁと思いました。 [/quote]
上の画像をご覧いただければ見えやすくなると思いますが、 ツリービューをもちいたテキストエディタで、内容をアーカイブ保存しようとしていますので、 Forループでノードの内容すべてを保存しようとしております。
mallocもcallocも試したのですが、同じだったのです…… あ!NULL文字!! 確かに+1がいるかも知れません。 後でABのテキスト見なおしてみます!!
とりあえず、いじり回って気がついたことと解決と疑問と続きの質問をば。
まず、私の [code]buffer=malloc(lstrlen(TreeName) + Len(Ex"\n")) lstrcat(buffer,TreeName) lstrcat(buffer,Ex"\n") [/code] ですが、連結かつ連結!となっています。 そりゃゴミつくわね…… [code]buffer=malloc(lstrlen(TreeName) + Len(Ex"\n")) lstrcpy(buffer,TreeName) lstrcat(buffer,Ex"\n") [/code] とするのが正解でした。
しかし、確保しているメモリ以上に連結してエラーが出なかったのはちょっと困りましたね…… もしかして、 [quote]※たまに、Heap block at ○○ modified at ×× past requested size of △と出ます(メモリが足り無い?) ※たまに、Invalid address specified to RtlFreeHeap(○○,☓☓ )と出ます(変なところに書き込まれている?) [/quote] これがそのエラーだったのかな……?
とりあえず、これで、おそらく、ファイルの保存はできたと思います。
保存は出来ました。 しかし、デバグ時に必ず、 Heap block at ○○ modified at ×× past requested size of △ が連発します。
なので、size of △の△をmallocするときに加えました。
エラーは消えますが、もちろん値が変わった時(例:△=3だった時にmallocで3を加えた。今度は△=6だとエラーが出る)に、 同じエラーが出るので、ちょっと腹が立ち、*2にするとエラーも出ず、値もしっかりファイルに保存されました。 何故*2にしたら保存されるのかが謎です。
あと、malloc、calloc関数ですが、これは上書きされるのかなぁ……? みたいな疑問も。
Dim a As *Byte a=malloc(10) lstrcpy(a,"test data") a=calloc(11) lstrcpy(a,"test dataA") free(a) のようなプログラムだと、どうなっているのかな……みたいな。 メモリAが確保されたまま、違うメモリBを確保し、メモリBだけ解放されてる…… となっているのでしょうか。 ……そうならないためのreallocなのかなぁ
さて、再度質問させて頂きます。 書き込んだデータを読み込むと、先と同様、いらぬ文字が付加されます。
[url=http://www.holygate.jpn.org/Data/3.jpg]保存したデータ[/url] ↓ [url=http://www.holygate.jpn.org/Data/4.jpg]読み込んだデータ[/url]
ツリーのノードを読み込む処理は、以下の様な感じです。 [code]'ツリー名を確認 ReadByte=SearchOneTextPointFormFile(hFile,Ex"\n",StartPoint) If ReadByte=0 Then Exit Do End If
TreeName=calloc(ReadByte)
'ファイルポインタを動かす SetFilePointer(hFile,StartPoint,0,FILE_BEGIN)
If ReadFile(hFile,TreeName,ReadByte,VarPtr(ReadFileLen),ByVal 0)=FALSE Then MessageBox(hMainWnd,Ex"ファイルの値が読み出せません\r\nError:TreeName","Error",MB_OK or MB_ICONWARNING) free(NodeInfo) free(TreeName) Exit Do End If
'検索開始ポイントをずらす StartPoint=StartPoint+ReadByte+1[/code]
SearchOneTextPointFormFile関数は以下のように定義しています。 [code]Function SearchOneTextPointFormFile(hFile As HFILE,Text As BytePtr,SearchStartPoint As Long) As Long Dim temp[0] As Byte Dim Count As Long Dim ReadFileLen As DWord Dim SearchPointLog As Long
'ファイルのポインタの位置を記録 SearchPointLog=SearchStartPoint
'ポインタを動かす SetFilePointer(hFile,SearchStartPoint,0,FILE_BEGIN)
Do If ReadFile(hFile,temp,1,VarPtr(ReadFileLen),ByVal 0)=FALSE or ReadFileLen=0 Then Exit Do End If
If lstrcmp(temp,Text)=0 Then SearchOneTextPointFormFile=Count
'ポインタを戻す SetFilePointer(hFile,SearchPointLog,0,FILE_BEGIN) Exit Function End If Count++ Loop
SearchOneTextPointFormFile=0 'ポインタを戻す SetFilePointer(hFile,SearchPointLog,0,FILE_BEGIN)
End Function[/code]
よろしくお願いいたします。
|
|
|
投稿記事 |
Posted: 2012年6月17日(日) 21:29 |
|
|
|
|
|
'書き込むデータを作成
① buffer=malloc(lstrlen(TreeName) + Len(Ex"\n"))
② Exit For
③ free(buffer)
②から Forで繰り返し処理をされているのかなと思いますが
③で開放したあと①でメモリ確保をしていますが
callocの説明に「malloc関数とは異なり、この関数ではメモリの0クリアを行います。」
とあり、mallocでは何かのデータが入っているかもしれないのが原因の1つではないかとおもったりしました。
①より 要るかいらないか分かりませんが文字列の最後は「0」で終わるようにしましょう的な事を
どっかで聞きかじっているので
buffer=malloc(lstrlen(TreeName) + Len(Ex"\n"))
↓
buffer=calloc(lstrlen(TreeName) + Len(Ex"\n") +1 )
のほうが安全ぽいなぁと思いました。
独学だけなので頓珍漢な返答でしたら
やさしさで全スルーしてあげてください。
'書き込むデータを作成 ① buffer=malloc(lstrlen(TreeName) + Len(Ex"\n")) ② Exit For ③ free(buffer)
②から Forで繰り返し処理をされているのかなと思いますが ③で開放したあと①でメモリ確保をしていますが callocの説明に「malloc関数とは異なり、この関数ではメモリの0クリアを行います。」 とあり、mallocでは何かのデータが入っているかもしれないのが原因の1つではないかとおもったりしました。 ①より 要るかいらないか分かりませんが文字列の最後は「0」で終わるようにしましょう的な事を どっかで聞きかじっているので buffer=malloc(lstrlen(TreeName) + Len(Ex"\n")) ↓ buffer=calloc(lstrlen(TreeName) + Len(Ex"\n") +1 ) のほうが安全ぽいなぁと思いました。
独学だけなので頓珍漢な返答でしたら やさしさで全スルーしてあげてください。
|
|
|
投稿記事 |
Posted: 2012年6月17日(日) 19:50 |
|
|
|
|
|
たかせ様
ご回答ありがとうございます。
引用: buffer=malloc(lstrlen(TreeName) + Len(Ex"\n"))
lstrcat(buffer,TreeName)
lstrcat(buffer,Ex"\n")
というのはソースコードをみるとTreeNameにデータがまったく設定されていません。
これは、
コード: Dim TreeName[256] As Byte
itm.mask = TVIF_TEXT
itm.pszText = TreeName
itm.cchTextMax = 256
itm.hItem = hHandle
SendMessage(hTree,TVM_GETITEM,0,VarPtr(itm) As LPARAM)
ここで、ノードのツリー名の値を取り込んでいます。
hTree=GetDlgItemText(hMainWnd,Treeview1)
のことです。
よろしくお願いいたします
たかせ様 ご回答ありがとうございます。
[quote]buffer=malloc(lstrlen(TreeName) + Len(Ex"\n")) lstrcat(buffer,TreeName) lstrcat(buffer,Ex"\n")
というのはソースコードをみるとTreeNameにデータがまったく設定されていません。 [/quote]
これは、 [code]Dim TreeName[256] As Byte
itm.mask = TVIF_TEXT itm.pszText = TreeName itm.cchTextMax = 256 itm.hItem = hHandle
SendMessage(hTree,TVM_GETITEM,0,VarPtr(itm) As LPARAM)[/code] ここで、ノードのツリー名の値を取り込んでいます。 hTree=GetDlgItemText(hMainWnd,Treeview1) のことです。
よろしくお願いいたします
|
|
|
投稿記事 |
Posted: 2012年6月17日(日) 04:05 |
|
|
|
|
|
下記のソースコード一目みて不思議に思いました。
buffer=malloc(lstrlen(TreeName) + Len(Ex"\n"))
lstrcat(buffer,TreeName)
lstrcat(buffer,Ex"\n")
というのはソースコードをみるとTreeNameにデータがまったく設定されていません。
lstrlen(TreeName) でOKですか?
lstrlen(TreeName)は上記のソースコードだと常時0となりますが?
ご確認願います。
もし見当違いだったらごめんなさい。
よろしくお願いします。
下記のソースコード一目みて不思議に思いました。
buffer=malloc(lstrlen(TreeName) + Len(Ex"\n")) lstrcat(buffer,TreeName) lstrcat(buffer,Ex"\n")
というのはソースコードをみるとTreeNameにデータがまったく設定されていません。
lstrlen(TreeName) でOKですか? lstrlen(TreeName)は上記のソースコードだと常時0となりますが?
ご確認願います。 もし見当違いだったらごめんなさい。 よろしくお願いします。
|
|
|
投稿記事 |
Posted: 2012年6月16日(土) 21:31 |
|
|
|
|
|
度々申し訳ありません。
前回のプログラムを作成している途中で、また躓いてしまいました。
ツリー型のテキストエディタを作っていて、それの作業ファイルをアーカイブにしようと思い、
以下のような構造でファイルを書き込んでいこうと考えました。
[ツリーのノードの種類(ルート、親、子など)] \n [ノードのテキスト] \n [ノードの内容のバイト数] \n [ノードの内容(テキストデータ)]\n
※\nは特殊文字(Ex"\n")のことです
※データは、0\nTitle\n3\nAAA\n........のように続きます
ここで、ノードのテキストを取得した時、なぜかデータにひどくノイズが入ります。
ソフトの画像(これの「ノードのタイトル」という文字を保存したい)
↓
余計な文字が入る(取得したバッファをMessageBox関数で表示)
この部分のプログラム
コード: 'ツリー名
Dim itm As TVITEM
Dim TreeName[256] As Byte
itm.mask = TVIF_TEXT
itm.pszText = TreeName
itm.cchTextMax = 256
itm.hItem = hHandle
SendMessage(hTree,TVM_GETITEM,0,VarPtr(itm) As LPARAM) '取得
'書き込むデータを作成
buffer=malloc(lstrlen(TreeName) + Len(Ex"\n"))
lstrcat(buffer,TreeName)
lstrcat(buffer,Ex"\n")
'wsprintf(buffer,Ex"%s\n",TreeName)
'書き込み
If WriteFile(hFile,buffer,lstrlen(TreeName) + lstrlen(Ex"\n"),VarPtr(WrittenByte),ByVal NULL)=FALSE Then
MessageBox(hMainWnd,"ツリー名の書き込みに失敗しました","Error",MB_OK or MB_ICONWARNING)
Exit For
End If
free(buffer)
※lstrlen(TreeName) + Len(Ex"\n")をMessageBox関数で表示すると、正当なバイト数が返されています
※wsprintfで最初にやっていましたが、出来なかったので方法を変えました。が、出来ませんでした。
※たまに、Heap block at ○○ modified at ×× past requested size of △と出ます(メモリが足り無い?)
※たまに、Invalid address specified to RtlFreeHeap(○○,☓☓ )と出ます(変なところに書き込まれている?)
こういうことをするのが初めてで、ものすごく長いコードになったため、一部分を抜粋して書かせて頂きました。
同様のコードをコピペして、 ノードの内容のバイト数、[ノードの内容(テキストデータ)の部分も作ったので同じようなエラーになります。
何かお分かりになられた方、いらっしゃいましたらご教授ください。
情報が足りなければ、かなり汚いコードにはなりますが記載させて頂きます。
よろしくお願いいたします。
度々申し訳ありません。
[url=http://www.activebasic.com/forum/viewtopic.php?t=3114]前回[/url]のプログラムを作成している途中で、また躓いてしまいました。
ツリー型のテキストエディタを作っていて、それの作業ファイルをアーカイブにしようと思い、 以下のような構造でファイルを書き込んでいこうと考えました。
[ツリーのノードの種類(ルート、親、子など)] \n [ノードのテキスト] \n [ノードの内容のバイト数] \n [ノードの内容(テキストデータ)]\n ※\nは特殊文字(Ex"\n")のことです ※データは、0\nTitle\n3\nAAA\n........のように続きます
ここで、ノードのテキストを取得した時、なぜかデータにひどくノイズが入ります。
[url=http://www.holygate.jpn.org/Data/1.jpg]ソフトの画像(これの「ノードのタイトル」という文字を保存したい)[/url] ↓ [url=http://www.holygate.jpn.org/Data/2.jpg]余計な文字が入る(取得したバッファをMessageBox関数で表示)[/url]
この部分のプログラム [code]'ツリー名 Dim itm As TVITEM Dim TreeName[256] As Byte
itm.mask = TVIF_TEXT itm.pszText = TreeName itm.cchTextMax = 256 itm.hItem = hHandle
SendMessage(hTree,TVM_GETITEM,0,VarPtr(itm) As LPARAM) '取得
'書き込むデータを作成 buffer=malloc(lstrlen(TreeName) + Len(Ex"\n")) lstrcat(buffer,TreeName) lstrcat(buffer,Ex"\n")
'wsprintf(buffer,Ex"%s\n",TreeName)
'書き込み If WriteFile(hFile,buffer,lstrlen(TreeName) + lstrlen(Ex"\n"),VarPtr(WrittenByte),ByVal NULL)=FALSE Then MessageBox(hMainWnd,"ツリー名の書き込みに失敗しました","Error",MB_OK or MB_ICONWARNING) Exit For End If free(buffer)[/code]
※lstrlen(TreeName) + Len(Ex"\n")をMessageBox関数で表示すると、正当なバイト数が返されています ※wsprintfで最初にやっていましたが、出来なかったので方法を変えました。が、出来ませんでした。 ※たまに、Heap block at ○○ modified at ×× past requested size of △と出ます(メモリが足り無い?) ※たまに、Invalid address specified to RtlFreeHeap(○○,☓☓ )と出ます(変なところに書き込まれている?)
こういうことをするのが初めてで、ものすごく長いコードになったため、一部分を抜粋して書かせて頂きました。 同様のコードをコピペして、 ノードの内容のバイト数、[ノードの内容(テキストデータ)の部分も作ったので同じようなエラーになります。
何かお分かりになられた方、いらっしゃいましたらご教授ください。 情報が足りなければ、かなり汚いコードにはなりますが記載させて頂きます。 よろしくお願いいたします。
|
|
|
投稿記事 |
Posted: 2012年6月16日(土) 01:08 |
|
|
|
|