我想包装一个小的C++代码分配与ctypes的阵列,并且有一些错误在一个c_void_p对象存储地址。包装C++动态数组与Python + ctypes的,段错误
(注意:该指针被故意投给void*
,“以后导致我想要做的分配的C++对象阵列相同的方式,太)
的C(++),以被包裹的功能:
void* test_alloc()
{
const int size = 100000000;
int* ptr = new int[size];
std::cout << "Allocated " << size * sizeof(int) << " bytes @ " <<
ptr << std::endl;
return static_cast<void*>(ptr);
}
void test_dealloc(void* ptr)
{
int* iptr = static_cast<int*>(ptr);
std::cout << "Trying to free array @ " << iptr << std::endl;
delete[] iptr;
}
Python的包装物(假设前者功能已经与ctypes的进口):
class TestAlloc(object):
def __init__(self):
self.pointer = ctypes.c_void_p(test_alloc())
print "self.pointer points to ", hex(self.pointer.value)
def __del__(self):
test_dealloc(self.pointer)
对于小阵列(例如,大小= 10),它似乎确定:
In [5]: t = TestAlloc()
Allocated 40 bytes @ 0x1f20ef0
self.pointer points to 0x1f20ef0
In [6]: del t
Trying to free array @ 0x1f20ef0
但是,如果我想分配一个大一个(大小= 100 000 000),会出现问题:
In [2]: t = TestAlloc()
Allocated 400000000 bytes @ 0x7faec3b71010
self.pointer points to 0xffffffffc3b71010L
In [3]: del t
Trying to free array @ 0xffffffffc3b71010
Segmentation fault
存储在ctypes.c_void_p地址显然是错误的,高4个字节无效。 不知何故32位和64位地址是混合的,并且在大数组分配的情况下,内存管理器(在这种情况下)被迫返回一个32位(thx TonJ)不可表示的地址。
是否有人可以提供这样的解决方法吗?
的代码被编译以克++ 4.4.3和在Ubuntu Linux 10.04 x86_64的与4G RAM中运行。 Python版本是2.6.5。
非常感谢!
更新:
我设法解决了这个问题。我忘记了为test_alloc()
指定restype。 restype的默认值是ctypes.c_int
,64位地址不适合。在test_alloc()
的呼叫之前还通过添加test_alloc.restype = ctypes.c_void_p
解决了该问题。
是的,正确制定。幸运的是,在大数组大小的情况下,内存管理器不得不将其分配到不再适合32位的地址,因此该错误变得明显。 – cornail 2010-06-23 10:34:24