我写的C扩展Python崩溃与“Abort trap:6”

时间:2014-11-05 13:05:16

标签: python c

#include <stdio.h>
#include <Python/Python.h>
#include <string.h>


char *baseN(int num, char *LETTERS);

int myHash(char *s, char *LETTERS);

int indexOfString(char *s, char c);

char *lstrip(char *s, char strp);


void removeFirst(char *s);


static PyObject *ex_baseN(PyObject *self, PyObject *args) {


    int num;

    char *LETTERS;

    if (!PyArg_ParseTuple(args, "is", &num, &LETTERS)) {
        Py_RETURN_NONE;
    }

    char *result = baseN(num, LETTERS);


    PyObject *retval = (PyObject *) Py_BuildValue("s", result);


    return retval;

}


static PyObject *ex_myHash(PyObject *self, PyObject *args) {
    char *s;
    char *LETTERS;

    if (!PyArg_ParseTuple(args, "ss", &s, &LETTERS)) {
        Py_RETURN_NONE;
    }

    int result = myHash(s, LETTERS);

    PyObject *retval = (PyObject *) Py_BuildValue("i", result);

    return retval;

}

static PyMethodDef foo_methods[] = {

        {"myHash", (PyCFunction) ex_myHash, METH_VARARGS},
        {"baseN", (PyCFunction) ex_baseN, METH_VARARGS},
        {NULL, NULL, 0, NULL}
};


PyMODINIT_FUNC initmyEx() {
    Py_InitModule3("myEx", foo_methods, "My first extension module.");

}


char *baseN(int num, char *LETTERS) {

    int len = strlen(LETTERS);


    if (num == 0) {
        char *result = (char *) malloc(sizeof(char));

        sprintf(result, "%c", LETTERS[0]);
        return result;
    }


    char *s = baseN(num / len, LETTERS);


    lstrip(s, LETTERS[0]);

    char *result = (char *) malloc(sizeof(char) * (strlen(s) + 1));


    int result_len = strlen(s) + 1;


    for (int i = 0; i < result_len; i++) {

        if (i < result_len - 1) {
            result[i] = s[i];
        } else {

            result[i] = LETTERS[num % len];
        }

    }

    return result;


}


void removeFirst(char *s) {
    int len = strlen(s);
    for (int i = 0; i < len; i++) {
        if (i < len - 1) {
            s[i] = s[i + 1];
        } else {
            s[i] = '\0';
        }
    }
}


char *lstrip(char *s, char strp) {

    int len = strlen(s);

    if (len >= 0) {

        if (s[0] == strp) {

            removeFirst(s);

        }
    }

    return s;

}


int myHash(char *s, char *LETTERS) {

    int h = 7;

    int len = strlen(s);

    for (int i = 0; i < len; i++) {
        int index = indexOfString(LETTERS, s[i]);
        h = 37 * h + index;
    }
    return h;
}


int indexOfString(char *s, char c) {
    int len = strlen(s);
    for (int i = 0; i < len; i++) {
        if (s[i] == c) {
            return i;
        }
    }
    return -1;
}



int main(){
    char * result = baseN(10119, "abcdefg");
    printf("%s\n",result);
    return 0;
}

我编写了上面的python扩展,但是在编译之后,在Python解释器ipython中运行,结果是:

In [4]: myEx.myHash('asdfg','ascfwdzxfxcg')

Out[4]: 485465319

In [5]: myEx.baseN(1000,'asdfghj')

Abort trap: 6

名为baseN的函数不起作用,为什么????

1 个答案:

答案 0 :(得分:1)

您的代码中存在缓冲区溢出:

char *baseN(int num, char *LETTERS) {

    int len = strlen(LETTERS);


    if (num == 0) {
        char *result = (char *) malloc(sizeof(char));  // 1 char allocated

        sprintf(result, "%c", LETTERS[0]); // 2 chars written including NUL char
        return result;
    }

当前的sprintf需求:

        char *result = malloc(2);