我正在做一些cython的实验,我遇到了一些意想不到的行为:
In [1]: %load_ext cython
In [2]: %%cython
...: cdef class foo(object):
...: cdef public char* val
...: def __init__(self, char* val):
...: self.val = val
...:
In [3]: f = foo('aaa')
In [4]: f.val
Out[4]: '\x01'
f.val
发生了什么?重复检查产生看似随机的输出,因此看起来f.val
指向无效的内存。
this question的答案表明您应该使用str
。
实际上,这个版本运行良好:
In [21]: %%cython
...: cdef class foo(object):
...: cdef public str val
...: def __init__(self, str val):
...: self.val = val
那么,第一个版本中发生了什么?似乎char*
在课堂建设后的某个时刻被释放,但我不清楚原因。
答案 0 :(得分:3)
在Cython中将Python字节串转换为char *
时,Cython会为您提供指向字符串对象内容的指针。这个原始指针不会影响字符串的Python引用计数(跟踪哪些指针引用哪些字符串是不可行的。)
当字符串的引用计数达到零并且字符串被回收时,指针变为无效。
除非您确实需要char *
,否则您不应将Python字节串转换为char *
s。如果这样做,请确保在需要char *
时保持对字符串的正常Python引用,以延长字符串的生命周期。