我找到了一个在python ctypes
中调整数组大小的答案from ctypes import *
list = (c_int*1)()
def customresize(array, new_size):
resize(array, sizeof(array._type_)*new_size)
return (array._type_*new_size).from_address(addressof(array))
list[0] = 123
list = customresize(list, 5)
>>> list[0]
123
>>> list[4]
0
如果我再次打电话:
list = customresize(list, 40)
它给出错误:
ValueError: Memory cannot be resized because this object doesn't own it
为什么它仅在您第一次拨打customresize()
时才有效?
我还看到了一个帖子的另一个答案:
def customresize(array, new_size):
return (array._type_*new_size).from_address(addressof(array))
此处customresize()
无论您拨打多少次都可以使用。
但它提出了另一个问题,我发现当你将list
调整为更大的大小时,我的python.exe不会使用更多的内存,这意味着没有为调整大小的list
分配内存。在没有分配的情况下为内存提供可访问性是非常危险的吗?为什么ctypes.resize
是这样设计的?真的很困惑......
答案 0 :(得分:2)
from_address
很危险,因为它无法确保您已分配正在访问的内存,因此可能导致应用程序崩溃或更糟。此外,它不拥有它所指向的内存,因此如果原始所有者被删除,则内存可以被重用于其他内容。
这里的一个选择是保持对原始数组的引用:
def customresize(array, new_size):
base = getattr(array, 'base', array)
resize(base, sizeof(array._type_)*new_size)
new_array = (array._type_*new_size).from_address(addressof(base))
new_array.base = base
或者更安全,你可以从旧的数组中创建一个新的数组:
list = (c_int * 5)(*list)
答案 1 :(得分:0)
让我自己总结一下这个问题。但请注意@ecatmur和其他人 resize()函数可用于调整现有ctypes对象的内存缓冲区的大小。该函数将对象作为第一个参数,并将请求的大小(以字节为单位)作为第二个参数。但是,调整大小的对象仍然基于其原始大小限制了对内存缓冲区的访问。解决问题。定义了3种不同的功能:
def customresize1(array, new_size):
resize(array, sizeof(array._type_)*new_size)
return (array._type_*new_size).from_address(addressof(array))
def customresize2(array, new_size):
return (array._type_*new_size).from_address(addressof(array))
def customresize3(array, new_size):
base = getattr(array, 'base', array)
resize(base, sizeof(array._type_)*new_size)
new_array = (array._type_*new_size).from_address(addressof(base))
new_array.base = base
所有函数都返回一个共享原始所有者内存的对象,该对象不拥有内存且无法调整大小(例如,在customresize1
中出错)
customresize2
会返回一个调整大小的数组,但请注意from_address不会为调整大小分配内存..
customresize3
保留拥有内存的基础对象的记录,但返回的对象不是内存的所有者
因为python正在动态分配它的内存和垃圾收集,所以,如果你想调整大小,只需重做大小就行了。例如:
list = (c_int * NEW_SIZE)()
或者您可能希望保留原始值:
list = (c_int * NEW_SIZE)(*list)