2014-11-05 72 views
0
#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運行後,其結果是:的C擴展的Python我寫崩潰,「中止陷阱:6」

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

Out[4]: 485465319 

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

Abort trap: 6 

名爲baseN的函數不起作用,爲什麼?

+0

爲什麼你的Python擴展模塊有一個'主()'?你能發佈你使用的編譯命令嗎? – 2014-11-05 13:15:37

+0

我使用main()函數做測試,當我添加python擴展名時,從distutils.core導入設置中刪除了 – lixudong 2014-11-05 13:26:29

+0

,擴展名爲 setup(name ='myEx',version ='1.0',ext_modules = [Extension 'myEx',['main.c'])]) – lixudong 2014-11-05 13:26:46

回答

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); 
+0

它的作品,你是我的上帝,謝謝! – lixudong 2014-11-05 13:30:23