tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトルZeroMemoryによる構造体配列の初期化について
記事No15060
投稿日: 2010/12/02(Thu) 13:50
投稿者ミルミ
はじめまして。

ミルミと申します。

VB6構造体の初期化をWin32APIのZeroMemory関数で行っています。

関数の第二引数(構造体の大きさ)にはLen(構造体名)を渡しています。

いま、要素数が可変(Redim Preserve 配列名(n)nは整数)の文字列配列
を複数個持つ構造体配列を使っているのですが、この構造体にデータを入れる前
(Redimを一度も行っていない場合)と値を入れたあと(たとえばUbound(配列名)の
値が120のとき)で、上記Len(構造体名)のサイズが同じままになっています。

ZeroMemory関数は構造体配列の初期化に使えますでしょうか。
エラーは発生しないのですが、使い方をまちがえていますでしょうか。
インデックスだけ初期化して値はメモリに残留していても差し支えありませんか。
個々の文字列配列を要素数だけ先に0クリアしてから構造体を0クリアすべきでしょうか。

構造体内の配列にはZeroMemoryを使わずにRedim 配列名(0) や
Erase 配列名 でクリアしたほうがよいでしょうか。

よろしくお願いします。

[ツリー表示へ]
タイトルRe: ZeroMemoryによる構造体配列の初期化について
記事No15061
投稿日: 2010/12/02(Thu) 16:32
投稿者魔界の仮面弁士
> (Redimを一度も行っていない場合)と値を入れたあと(たとえばUbound(配列名)の
> 値が120のとき)で、上記Len(構造体名)のサイズが同じままになっています。
静的配列の場合は、ユーザー定義型の一部として確保されますが、
動的配列の場合、その要素はユーザー定義型とは別の場所に確保されており、
ユーザー定義型は、その場所を指し示す4バイトのアドレス値のみを記録しています。


> ZeroMemory関数は構造体配列の初期化に使えますでしょうか。
ユーザー定義型のレイアウトによっては、メモリ上の位置が連続していない場合や、
クリアしてはいけない領域が含まれている可能性があるため、そのような場合には、
全体を一括クリアするのではなく、必要なエリアごとに処理する必要があります。

それらを踏まえたうえで、メモリ上の配置を理解して使う分には OK でしょう。


> Redim 配列名(0) や Erase 配列名 でクリアしたほうがよいでしょうか。
その方が安全でしょうね。なお、Redim 配列名(0) と Erase 配列名 は別の処理です。


> VB6構造体の初期化をWin32APIのZeroMemory関数で行っています。
> 関数の第二引数(構造体の大きさ)にはLen(構造体名)を渡しています。
Len ≠ LenB なユーザー定義型の場合は、パディングに注意が必要です。

VB6 のユーザー定義型は、各メンバーが 32bit の境界を跨がないように配置されます。
Len 関数が返すのは再配置前の値、LenB は再配置後のサイズを返します。

Option Explicit

Private Type a
    p1 As Byte
    v(7) As Integer
    p2 As Byte
End Type

Private Type b
    p1 As Byte
    v() As Integer
    p2 As Byte
End Type

Private Sub Form_Load()
    Dim x As a
    Dim y As b
    
    Debug.Print "静的配列 : a", Len(x), LenB(x)
    Debug.Print "初期化前 : b", Len(y), LenB(y)
    ReDim y.v(7)
    Debug.Print "初期化後 : b", Len(y), LenB(y)
End Sub

------------- 実行結果
静的配列 : a   18    20
初期化前 : b    6    12
初期化後 : b    6    12
-------------
http://support.microsoft.com/kb/137729/ja

[ツリー表示へ]
タイトルRe^2: ZeroMemoryによる構造体配列の初期化について
記事No15068
投稿日: 2010/12/20(Mon) 10:10
投稿者ミルミ
魔界の仮面弁士 様

返信くださり有難うございます。

配列の使い方や初期化に関し、貴重なご説明はとても参考になりました。
処理方法に関し、再設計と検証とをしなければならないことが明確になりました。

今後ともよろしくお願い申し上げます。

ミルミ

[ツリー表示へ]