python ctypes:如何释放内存?获取无效指针错误[英] Python ctypes: how to free memory? Getting invalid pointer error

本文是小编为大家收集整理的关于python ctypes:如何释放内存?获取无效指针错误的处理方法,想解了python ctypes:如何释放内存?获取无效指针错误的问题怎么解决?python ctypes:如何释放内存?获取无效指针错误问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

我想从带有ctypes的C/C ++库中获取一些字符串,为Python.我的代码看起来像这样:

lib中的代码:

const char* get(struct something *x) 
{
    [...]
    // buf is a stringstream
   return strdup(buf.str().c_str());
}

void freeme(char *ptr)
{
    free(ptr);
}

Python代码:

fillprototype(lib.get, c_char_p, POINTER(some_model)])
fillprototype(lib.freeme, None, [c_char_p])

// what i want to do here: get a string into python so that i can work
// with it and release the memory in the lib.
c_str = lib.get(some_model)
y = ''.join(c_str)
lib.freeme(c_str) 

如果我print()c_str,一切都在那里.问题是(或似乎是)在上一条线路中.我无法释放内存 - 图书馆的指针错误.我在这里做错了什么? (并且请不要建议BOOST :: PYTHON左右).

*** glibc detected *** python2: munmap_chunk(): invalid pointer: 0x00000000026443fc ***

推荐答案

正如David Schwartz指出的那样,如果将Restype设置为c_char_p,CTYPES会返回常规的Python字符串对象.解决此问题的一种简单方法是使用void *并施放结果:

string.c:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

char *get(void)
{
    char *buf = "Hello World";
    char *new_buf = strdup(buf);
    printf("allocated address: %p\n", new_buf);
    return new_buf;
}

void freeme(char *ptr)
{
    printf("freeing address: %p\n", ptr);
    free(ptr);
}

python用法:

from ctypes import *

lib = cdll.LoadLibrary('./string.so')
lib.freeme.argtypes = c_void_p,
lib.freeme.restype = None
lib.get.argtypes = []
lib.get.restype = c_void_p

>>> ptr = lib.get()
allocated address: 0x9facad8
>>> hex(ptr)
'0x9facad8'
>>> cast(ptr, c_char_p).value
'Hello World'
>>> lib.freeme(ptr)
freeing address: 0x9facad8

您也可以使用c_char_p的子类.事实证明,CTYPES未针对简单类型的子类调用getfunc.

class c_char_p_sub(c_char_p):
    pass

lib.get.restype = c_char_p_sub

value属性返回字符串.您可以将参数留为freeme,为更通用的c_void_p.接受任何指针类型或整数地址.

其他推荐答案

释放内存的便宜hack是在静态上分配它,而永远不会释放它.当然,只有知道最大的金额,并且如果您知道在第二次打电话之前就已经完成了,则有效.

static char _externalStringBuffer[MAX_BUFFER_SIZE];
char *get() {
    // put characters in _externalStringBuffer
    return _externalStringBuffer;
}

本文地址:https://www.itbaoku.cn/post/358957.html