簡體   English   中英

使用Python + ctypes,segfault包裝C ++動態數組

[英]Wrapping C++ dynamic array with Python+ctypes, segfault

我想包裝一個小的C ++代碼,用ctypes分配一個數組,並且將地址存儲在c_void_p對象中有問題。

(注意:有意地將指針強制轉換為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)

對於小數組(例如size = 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)上無法表示的地址。

有人可以為此提供解決方法嗎?

該代碼已使用g ++ 4.4.3編譯,並在帶有4G RAM的Ubuntu Linux 10.04 x86_64上運行。 Python版本是2.6.5。

非常感謝你!

更新:

我設法解決了這個問題。 我忘了為test_alloc()指定restype。 restype的默認值是ctypes.c_int ,64位地址不適合。 通過在調用test_alloc()之前添加test_alloc.restype = ctypes.c_void_p解決了問題。

從它看來,似乎問題不在於小/大陣列分配,而是在32位和64位地址的混合中。 在您的示例中,小數組的地址適合32位,但大數組的地址不適合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM