[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2004/08/26(Thu) 10:46
投稿者名:溝田 千寿喜
Eメール:どうも!
URL :
タイトル:
変数の内容のメモリ上の扱いについて
いつも楽しく拝見させていただいてます。
今日は、変数の内容がメモリ上で、どのように扱われてるのか
色々確認したいのです。
バージョンは6.0です。

例えば、
dim Suu as Integer
Suu=40
の例では、メモリの内容は
0010,1000になるんですよね?

Long型でも同じで、↓の例では、
dim LSuu as Long
Long=50000
1100,0011,0101,0000と扱われますよね?


それでは、固定長のString型の場合なんですが、
dim Str as String *1
Str="a"
"a"のアスキーコードは97ですが、VBの場合半角文字も2バイトとして
扱われるので、
0000,0000,0110,0001
でいいんですか?

あと、可変長のString型の場合メモリの内容はどうなりますか?
例えば
dim Str2 as String
Str2="b"
の場合。

投稿時間:2004/08/26(Thu) 10:48
投稿者名:溝田 千寿喜
Eメール:どうも!
URL :
タイトル:
Re: 変数の内容のメモリ上の扱いについて
追伸。
変数の内容が、メモリ上でどのように扱われているかを調べられる、
関数とかありませんか?

投稿時間:2004/08/28(Sat) 00:03
投稿者名:通りすがり
Eメール:
URL :
タイトル:
Re^2: 変数の内容のメモリ上の扱いについて
私も以前それで苦労しました。
あったら本当に教えてほしいです。

投稿時間:2004/08/28(Sat) 17:19
投稿者名:Say
Eメール:
URL :
タイトル:
Re^3: 変数の内容のメモリ上の扱いについて
>> 変数の内容が、メモリ上でどのように扱われているかを調べられる、
>> 関数とかありませんか?
> 私も以前それで苦労しました。
> あったら本当に教えてほしいです。

なんでも関数で揃ってたら、プログラマは不要になってしまいます。
ないものは作ってください。

たとえばこう。(良い子はまねしないでね。)

Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" _
            Alias "RtlMoveMemory" _
            (ByVal Destination As Long, _
             ByVal Source As Long, _
             ByVal Length As Long)

Private Sub Command1_Click()
    Dim Suu As Integer
    Dim LSuu As Long
    Dim Str1 As String * 1
    Dim Str2 As String
    Dim bBuf(10) As Byte
    Suu = 40
    LSuu = 50000
    Str1 = "a"
    Str2 = "b"
    CopyMemory VarPtr(bBuf(0)), VarPtr(Suu), Len(Suu)
    MsgBox dispVar(bBuf(), Len(Suu))
    CopyMemory VarPtr(bBuf(0)), VarPtr(LSuu), Len(LSuu)
    MsgBox dispVar(bBuf(), Len(LSuu))
    CopyMemory VarPtr(bBuf(0)), StrPtr(Str1), LenB(Str1)
    MsgBox dispVar(bBuf(), LenB(Str1))
    CopyMemory VarPtr(bBuf(0)), StrPtr(Str2), LenB(Str2)
    MsgBox dispVar(bBuf(), LenB(Str2))
End Sub
Function dispVar(param1() As Byte, param2 As Long)
    Dim i As Long
    Dim ret As String
    ret = toBin(param1(0))
    For i = 1 To param2 - 1
        ret = ret & "," & toBin(param1(i))
    Next
    dispVar = ret
End Function
Function toBin(ByVal param As Byte) As String
    Dim i As Long
    Dim ret As String
    ret = ""
    For i = 0 To 7
        ret = CStr(param Mod 2) & ret
        param = param \ 2
    Next
    toBin = ret
End Function

投稿時間:2004/08/28(Sat) 17:27
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re: 変数の内容のメモリ上の扱いについて
> 今日は、変数の内容がメモリ上で、どのように扱われてるのか
> 色々確認したいのです。

それは、何のためにでしょうか?
どのような状況を想定しているのかによってデータの扱われ方は変わってきます。

整数の場合は、さほど差は無いのですが、特に文字列型やユーザー定義型の場合、
APIに引き渡す場合、OLE APIに引き渡す場合、バイナリファイルにPut#する場合とで
データの配置が変化する事がありますので…。


> dim Suu as Integer
> Suu=40
> の例では、メモリの内容は
> 0010,1000になるんですよね?
2進数表記でいえば、そうなりますね。ただ、Integer は2バイトなので、
  0000,0000,0010,1000
と表記した方が良いかも知れませんけれども。
16進数表記で言えば、&H0028 といった所でしょうか。

で、そのデータが、
  Debug.Print VarPtr(Suu)
で示されるメモリ位置に、2バイト分書き込まれていますので、
  VarPtr(Suu) + 0 の位置に書かれているデータ …… &H28 ( 40)
  VarPtr(Suu) + 1 の位置に書かれているデータ …… &H00 (  0)
のように、メモリ上に配置されています。


> dim LSuu as Long
> Long=50000
> 1100,0011,0101,0000と扱われますよね?
2進数なら 0000,0000,0000,0000,1100,0011,0101,0000。
16進数なら 00 00 C3 50 ですかね。
  Debug.Print CLng("&H0000C350") = 50000&

そのデータが、
  Debug.Print VarPtr(LSuu)
で示されるメモリ位置に、4バイト分書き込まれている事になりますので、
  VarPtr(LSuu) + 0 の位置に書かれているデータ …… &H50 ( 80)
  VarPtr(LSuu) + 1 の位置に書かれているデータ …… &HC3 (195)
  VarPtr(LSuu) + 2 の位置に書かれているデータ …… &H00 (  0)
  VarPtr(LSuu) + 3 の位置に書かれているデータ …… &H00 (  0)
のように配置される事になります。


> dim Str2 as String
> Str2="b"
> の場合。
この場合、
  Debug.Print VarPtr(Str2)
で示されるメモリ位置からの4バイト分に、その変数が保持する
文字列値のメモリ位置が書き込まれています。

なお、そのアドレスが示すメモリ位置に格納されている情報は、
  Debug.Print StrPtr(Str2)
で得られる値と常に等しく、これが文字列"b"の先頭アドレスを意味しています。


そして、この文字列アドレスが示す値が &H00000000 だった場合、この変数の中身は
空文字列、すなわち vbNullString であるという事になります。
そして、文字列のアドレス値が &H00000000 以外だった場合には、この変数 Str2 の中に、
「0文字以上の文字列」が含まれている事になるわけです。


この時、Str2 に、何らかの(vbNullString以外の)文字列が含まれている場合、
そこに含まれるデータの長さが、
  Debug.Print StrPtr(Str2) - 4
で示されるメモリ位置からの4バイト分に格納されています。

例えば、このアドレスが示すメモリ位置に格納されている情報が「0」と
なっていれば、長さゼロの文字列 "" が格納されている事になります。
今回の場合は、"b" が格納されているため、LenB("b") = &H00000002 なので、
  StrPtr(Str2) - 4 が示す位置に書かれているデータ …… &H02 (  2)
  StrPtr(Str2) - 3 が示す位置に書かれているデータ …… &H00 (  0)
  StrPtr(Str2) - 2 が示す位置に書かれているデータ …… &H00 (  0)
  StrPtr(Str2) - 1 が示す位置に書かれているデータ …… &H00 (  0)
といった感じですね。

そして、"b" の場合、AscW("b") = &H0062 ですので、2バイト分のデータが
  StrPtr(Str2) + 0 が示す位置に書かれているデータ …… &H62 ( 98)
  StrPtr(Str2) + 1 が示す位置に書かれているデータ …… &H00 (  0)
のように格納されます。


もし、Str2 = "あい" だったなら、LenB("あい") = &H00000004、そして
AscW("あ") = &H3042、AscW("い") = &H3044 なので、
  StrPtr(Str2) - 4 が示す位置に書かれているデータ …… &H04 (  4)
  StrPtr(Str2) - 3 が示す位置に書かれているデータ …… &H00 (  0)
  StrPtr(Str2) - 2 が示す位置に書かれているデータ …… &H00 (  0)
  StrPtr(Str2) - 1 が示す位置に書かれているデータ …… &H00 (  0)

  StrPtr(Str2) + 0 が示す位置に書かれているデータ …… &H42 ( 66)
  StrPtr(Str2) + 1 が示す位置に書かれているデータ …… &H30 ( 48)
  StrPtr(Str2) + 2 が示す位置に書かれているデータ …… &H44 ( 68)
  StrPtr(Str2) + 3 が示す位置に書かれているデータ …… &H30 ( 48)
という感じです。

投稿時間:2004/08/28(Sat) 20:55
投稿者名:Say
Eメール:
URL :
タイトル:
Re^2: 変数の内容のメモリ上の扱いについて
もしかして、No.189見て、これだけの解説書いて、UPするまで8分以内?

投稿時間:2004/08/28(Sat) 23:27
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^3: 変数の内容のメモリ上の扱いについて
> もしかして、No.189見て、これだけの解説書いて、UPするまで8分以内?
まさか。(^^;)  回答を書いているうちに、Sayさんに先を越されただけですよん。
検証のコード書きも含めると、20分程度かな?

# それはそうと、No.5 の投稿、気付いてもらえて無いのかなぁ…。

投稿時間:2004/08/29(Sun) 07:44
投稿者名:花ちゃん
Eメール:
URL :
タイトル:
Re^4: 変数の内容のメモリ上の扱いについて
> # それはそうと、No.5 の投稿、気付いてもらえて無いのかなぁ…。

すみませーん。 あの記事は気が付きませんでした。<m(__)m>

投稿時間:2004/08/31(Tue) 09:19
投稿者名:溝田 千寿喜
Eメール:どうも!
URL :
タイトル:
Re^5: 変数の内容のメモリ上の扱いについて
有難うございました。
とても、参考になりました。