2013-06-28 3 views
0
#include <Python.h> 

int isCodeValid() { 
    char *base = calloc(512, 1); 
// free(base); 
// base = calloc(512,1); 
    base = realloc(512, 1); 
    free(base); 
    return 1; 
} 

static PyMethodDef CodecMethods[] = { 
     { NULL, NULL, 0, NULL } }; 

PyMODINIT_FUNC inittest(void) { 
    //check for the machine code 
    //Py_FatalError 

    if (isCodeValid() != 0) 
     printf("nothing\n"); 
    else { 
     printf("starting ... \n"); 
    } 
    (void) Py_InitModule("test", CodecMethods); 
} 

выше простое расширение с использованием перераспределить здесь является setup.pyПочему python c расширение потерял указатель трассировки после realloc?

# coding=utf-8 
from distutils.core import setup, Extension 
import os 

cfd = os.path.dirname(os.path.abspath(__file__)) 


module1 = Extension('test', sources=["test.c"]) 

setup(name='test', version='0.2', description='codec for test', 
     ext_modules=[module1],) 

import test 

после компиляции с: python2.7 setup.py build_ext --inplace --force

I получаю сообщение об ошибке:

Python(30439) malloc: *** error for object 0x200: pointer being realloc'd was not allocated 
*** set a breakpoint in malloc_error_break to debug 

но используя

free(base); 
base = calloc(512,1); 

отлично работает без ошибок

Все, что я перепутались здесь?

+0

извините за вину, я пропустил realloc() – davyzhang

ответ

2

Первый аргумент realloc() должен быть указателем, а не int литеральным, в ранее выделенную память (или NULL). 512 отбрасывается указателем, и жалоба правильна, что память ранее не была назначена.

Для исправления:

/* Don't do this: 

     base = realloc(base, 512); 

    because if realloc() fails it returns NULL 
    and does not free(base), resulting in memory 
    remaining allocated and the code having no way 
    to free it: a memory leak. 
*/ 

char* tmp = realloc(base, 512); 
if (tmp) 
{ 
    base = tmp; 
} 

компилировать с предупреждением уровня на максимуме как компилятор выдаст предупреждение делает указатель из целого числа или аналогичных. И не игнорируйте предупреждения, желательно рассматривать их как ошибки.

+0

Большое спасибо, эта идиома очень полезна. BTW realloc действительно сложно использовать в расширении, он изменит адрес указателя, если он используется в расширении python/go, это сделает первый выделенный указатель в значении go/python бесполезным для освобождения. Должен ухватиться за последний возвращенный, чтобы освободить его. – davyzhang