Python中使用sorted对ctypes结构体指针列表排序引发内存耗尽问题的求助
问题原因与解决方案
你遇到的问题根本不是sorted不能处理ctypes结构体指针,而是你把单个的指针当成了可迭代的序列来处理,导致Python无限制地读取内存直到耗尽。
为什么原来的代码会内存耗尽?
detect.restype = POINTER(DETECTION)返回的是一个指向DETECTION结构体数组的首地址指针,它本身不是Python的列表或可迭代集合。当你直接把这个指针传给sorted时,Python会尝试迭代它——也就是不断通过指针偏移读取det[0], det[1], det[2]... 但它不知道什么时候停止,会一直读内存直到触及非法区域,最终被系统强制杀死(输出"Killed")。
优雅的解决步骤
要正确排序,你需要先获取检测结果的数量(共享库肯定会提供这个信息,要么通过返回值,要么通过输出参数),然后把指针指向的结构体数组转换成Python列表,再用sorted处理。
1. 确保获取检测结果数量
假设你的C共享库中detect函数的签名类似这样(会输出检测到的目标数量):
DETECTION* detect(/* 你的输入参数 */, int* out_num_detections);
那在Python中需要修改argtypes,添加一个接收数量的输出参数:
# 定义一个变量用来接收检测结果的数量 num_detections = c_int() # 更新detect的参数类型,最后一个参数是输出数量的指针 detect.argtypes = [/* 你的其他输入参数类型 */, POINTER(c_int)] detect.restype = POINTER(DETECTION)
2. 调用函数并转换为Python列表
调用时传入数量变量的指针,然后通过切片把指针数组转成Python列表(ctypes的指针支持切片操作,只要你知道长度):
# 调用检测函数,传入数量指针 dets_ptr = detect(/* 你的输入参数 */, byref(num_detections)) # 把指针数组转换成Python列表,只取前num_detections.value个元素 dets_list = dets_ptr[:num_detections.value]
3. 正常排序
现在就可以用sorted优雅地排序了:
sorted_dets = sorted(dets_list, key=lambda det: det.prob, reverse=True)
额外提醒
别忘了调用共享库提供的内存释放函数(如果有的话),避免内存泄漏:
# 假设共享库有free_detections函数用来释放检测结果内存 lib.free_detections(dets_ptr)
内容的提问来源于stack exchange,提问作者nOpe
相关产品推荐
相关产品推荐

