由于word_idxs[token] = row
语句,下面的cython代码崩溃了。如果我删除该声明一切正常。以下是我的观察
token
,程序在不同时间针对token
的不同值崩溃(这不是导致错误的特定单词)word_idxs[row]=row
,错误仍然存在。所以我认为错误与字符串无关word_idxs['constant'] = row
cmatrix[row, col] = fval
,那么一切正常我是Cython的新手,如果我做了一些根本错误的事情,请指出
def cload(self, file_path, int dim, long vocab_size):
print("Loading")
cdef:
unsigned int row = 0
int col = 0
float [:,:] cmatrix
cdef dict word_idxs = {}
char* token
char* line
matrix = np.zeros([vocab_size, dim], dtype=np.dtype('f'))
cmatrix = matrix
with open(file_path, 'rb') as f:
for line in f:
token = strtok(line, ' \n')
print(row, token)
word_idxs[token] = row
for col in range(dim) :
val = strtok(NULL,' ')
fval = atof(val)
cmatrix[row, col] = fval
row += 1
答案 0 :(得分:1)
对我来说最明显的问题是您没有对token
或val
的输出进行错误检查。如果NULL
到达字符串的末尾,则可以是strtok
,而您只是不处理此问题。由于缺乏可验证的例子,很难知道实际问题是什么
然后有几个问题,@ ead在评论中指出:
Python字符串应该是不可变的,但strtok
会修改它给出的指针。这不太可能导致您看到的崩溃,但可能会导致Python出现问题。
line
很可能是一个无效的指针(因为它所基于的Python对象永远不会被保留)
我认为这些问题可以用
这样的方法解决cdef char* line_ptr
for line in f: # line IS NOT TYPED
line_ba = bytearray(line) # bytearray is mutable - changing it is fine
line_ptr = line_ba # line_ptr is valid as long as line_ba exists
你的代码和我建议的替代品在Python和C字符串之间有很多转换,这从来都不是非常快(而且难以正确)。看起来像是用Python编写最简单的东西 - 我怀疑你真的从C调用中获益。