Eryk Sun added the comment:

If your goal is to get a bytes object, I don't see the point of creating an 
array. string_at is simpler and more efficient. 

If you really must create an array, note that simple pointers (c_void_p, 
c_char_p, c_wchar_p) need special handling. They don't have a `contents` 
attribute, and their _type_ is a string. 

Also, I think combining from_address and addressof is a bit convoluted. I think 
it's cleaner to implement this using an array pointer:

    >>> ptr = POINTER(c_int)((c_int * 3)(1,2,3))
    >>> arr = POINTER(ptr._type_ * 3)(ptr.contents)[0]
    >>> arr[:]
    [1, 2, 3]

This also keeps the underlying ctypes object(s) properly referenced:

    >>> arr._b_base_
    <__main__.LP_c_int_Array_3 object at 0x7fb28471cd90>
    >>> arr._b_base_._objects['0']['1']
    <__main__.c_int_Array_3 object at 0x7fb28477da60>

whereas using from_address creates an array that dangerously doesn't own its 
own data and doesn't keep a reference to the owner:

    >>> arr2 = (ptr._type_ * 3).from_address(addressof(ptr.contents))
    >>> arr2._b_needsfree_
    0
    >>> arr2._b_base_ is None
    True
    >>> arr2._objects is None
    True

Let's create a larger array to ensure it's using an mmap region instead of the 
heap. This ensures a segfault when trying to access the memory block after it's 
deallocated:

    >>> ptr = POINTER(c_int)((c_int * 100000)(*range(100000)))
    >>> arr = (ptr._type_ * 100000).from_address(addressof(ptr.contents))
    >>> del ptr
    >>> x = arr[:]
    Segmentation fault (core dumped)

whereas using a dereferenced array pointer keeps the source data alive:

    >>> ptr = POINTER(c_int)((c_int * 100000)(*range(100000)))
    >>> arr = POINTER(ptr._type_ * 100000)(ptr.contents)[0]
    >>> del ptr
    >>> x = arr[:]
    >>> x[-5:]
    [99995, 99996, 99997, 99998, 99999]

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue27274>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to