#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的函数不起作用,为什么????
答案 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);