pythonmemorybytememoryview

Use `ctypes.string_at` to check the memory of a `memoryview` object


In Python, memoryview gets a viewer for internal memories of bytes, bytearrays or whatever supports buffer protocal. If I use ctypes.string_at to get the value at the memory address shown by a memoryview object, I cannot get any information about the original object, like this(an interactive console):

>>> from ctypes import string_at
>>> from sys import getsizeof
>>> a = b'abc'
>>> b = memoryview(a)
>>> b
<memory at 0x7fb8e99c8408>
>>> string_at(0x7fb8e99c8408, getsizeof(a))
b'\x02\x00\x00\x00\x00\x00\x00\x00@\x0e\x8a\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00H\x10\x96\xe9\xb8\x7f\x00\x00\xff\xff\xff\xff'

The results show no evidence of b'abc'. So what exactly does the memory 0x7fb8e99c8408 mean in the object string of memoryview object? Can we verify the memory directly to demonstrate that the memoryview surely reflect the internal memory?


Solution

  • This is the address of the memoryview object in memory not the string object itself (assuming CPython implementation). In order to see the string bytes you need id(s) or id(memv.obj):

    >>> import sys
    >>> import ctypes
    >>> s = b"abc"
    >>> memv = memoryview(s)
    >>> s_mem = ctypes.string_at(id(s), sys.getsizeof(s))
    >>> s_mem
    b'\x02\x00\x00\x00\x00\x00\x00\x00`\xa2\x90\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00CBT+\xa6\xce&\xa5abc\x00'
    >>> s_mem[-len(s)-1:]
    b'abc\x00'
    

    If you're curious about the output you can read more about string object representation in Python here.