`python'出错:大小与prev_size相比已损坏

时间:2017-06-27 11:57:20

标签: python c

我使用c来编写python扩展名 我使用c程序加密字符串 我的c程序:

#include <Python.h>

static const char *codes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static const unsigned char map[256] = {
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 255,
        255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
        52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
        255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
        7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,
        19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,
        255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
        37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
        49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255
};

int length(char *str){
    int i = 0;
    while (str[i] != '\0') i++;
    return i;
}

char *str_encrypt(char *in) {
    unsigned long len = (unsigned long)length(in);
    unsigned long index, l_even;
    char *p;
    char *out = (char *) PyMem_Malloc (len * 4 / 3 + 1);
    p = out;
    /* valid output size ? */
    l_even = 3 * (len / 3);
    for (index = 0; index < l_even; index += 3) {
        *p++ = codes[in[0] >> 2];
        *p++ = codes[((in[0] & 3) << 4) + (in[1] >> 4)];
        *p++ = codes[((in[1] & 0xf) << 2) + (in[2] >> 6)];
        *p++ = codes[in[2] & 0x3f];
        in += 3;
    }
    /* Pad it if necessary...  */
    if (index < len) {
        unsigned a = (unsigned)in[0];
        unsigned b = (unsigned)((index+1 < len) ? in[1] : 0);
        unsigned c = 0;
        *p++ = codes[a >> 2];
        *p++ = codes[((a & 3) << 4) + (b >> 4)];
        *p++ = (char)((index+1 < len) ? codes[((b & 0xf) << 2) + (c >> 6)] : '=');
        *p++ = '=';
    }
    /* append a NULL byte */
    *p = '\0';
    return out;
}

static PyObject *wrap_encrypt_str(PyObject *self, PyObject *args) {
    char *input_str;
    if (!PyArg_ParseTuple(args, "s", &input_str)) {
        return NULL;
    }
    char *result = str_encrypt(input_str);
    PyObject *pyObject = Py_BuildValue("s", result);
    PyMem_Free(result);
    return pyObject;
}

/* registration table  */
static PyMethodDef wrap_methods[] ={
        {"encrypt_str", wrap_encrypt_str, METH_VARARGS},       /* method name, C func ptr, always-tuple */
        {NULL, NULL}                   /* end of table marker */
};

/* module initializer */
PyMODINIT_FUNC initencryption(void)                       /* called on first import */
{                                      /* name matters if loaded dynamically */
    (void) Py_InitModule("encryption", wrap_methods);   /* mod name, table ptr */
}

然后我写了一个名为setup.py的文件。
setup.py中的程序在这里:

from setuptools import setup, Extension
setup(
    name="extest",
    packages=["extest", "extest.math", "extest.test"],
    version="0.0.1",
    zip_safe=False,
    ext_modules=[
        Extension("extest.test.encryption", sources=['extest/test/encryption.c'], extra_compile_args=["-Wno-char-subscripts"])
    ],
    long_description='',
    classifiers=[
        "Environment :: Web Environment",
        "Intended Audience :: Developers",
        "Operating System :: OS Independent",
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 2.6',
        'Programming Language :: Python :: 2.7'
    ]
)

我运行python setup.py install并成功安装扩展程序 我在python程序中导入模块 像这样:

from extest.test.encryption import encrypt_str
a = encrypt_str("asdfg")
print a

成功运行。
但是当我用a = encrypt_str("asdfg")替换a = encrypt_str("/static/hello.js")时,我收到错误,程序崩溃了! 错误信息在这里:

*** Error in `python': corrupted size vs. prev_size: 0x0000000000aaca00 ***

是什么原因?如何解决?

2 个答案:

答案 0 :(得分:3)

你没有为值out设置malloc足够的内存, 我将此行代码char *out = (char *) PyMem_Malloc (len * 4 / 3 + 1);修改为char *out = (char *) PyMem_Malloc (len * 2);,然后重新生成此程序。我看到问题已经解决了。

答案 1 :(得分:0)

您在3个字节的块中迭代in,并为每个块写入4个字节到out。然后,最后,你用4个字节填充(如果in不是3的倍数),最后,你附加一个空字节。

所以你需要分配4 * ((len + 2) / 3) + 1个字节。

为了验证这是否正确,我们可以看一些小例子: 如果len为0,则只需要1个字节用于null。 如果len是1或2,则需要4个字节的填充,加上null。 如果len为3,则单个块需要4个字节,加上null。 如果len为4,则单个块需要4个字节,加上4个字节的填充,加上null。 等等。