我正在用C语言编写一个python扩展模块。当我在该模块的函数中声明大于4个元素的结构数组时,Python停止运行。
我正在编写模块以提高性能。
我已经声明了3个结构(“ SKU”,“ Cromosoma”,“ Aptitud”),我想创建一个Cromosoma数组,但是当我尝试创建包含4个以上元素的数组时,它就会中断。
// need_for_speed.c extension module code
#include <Python.h>
#include <stdlib.h>
#define MAX_GENES_SIZE 2000
typedef struct{
char codigo[30];
double venta;
char nombre[100];
double categoria;
double peso;
double ubicacion_especifica;
double ubicacion_actual;
double ubicacion_a_mover;
double stock;
} SKU;
typedef struct{
double ubicaciones_rompe_regla;
double cercania_medio;
double desv_std_picks_x_seccion;
double peso_x_ubicacion;
} Aptitud;
typedef struct{
SKU genes[MAX_GENES_SIZE];
Aptitud aptitud;
int genes_size;
int edad;
}Cromosoma;
static PyObject* prueba(PyObject* self, PyObject* args){
Cromosoma a;
SKU s;
strcpy(s.codigo,"1212");
a.genes[0] = s;
Cromosoma poblacion[] = {a,a,a,a,a};
printf("codigo %s ", poblacion[0].genes[0].codigo);
return PyLong_FromDouble(1);
}
static PyMethodDef Methods[] = {
{"prueba", prueba, METH_NOARGS, "Prueba general"},
{ NULL, NULL, 0, NULL }
};
// Module Definition struct
static struct PyModuleDef need_for_speed = {
PyModuleDef_HEAD_INIT,
"need_for_speed",
"Modulo para aumento de la velocidad de procesamiento para el algoritmo genético",
-1,
Methods
};
// Initialize module
PyMODINIT_FUNC PyInit_need_for_speed(void)
{
PyObject *m;
m = PyModule_Create(&need_for_speed);
return m;
}
setup.py来构建此模块:
from distutils.core import setup, Extension
setup(name = 'need_for_speed', version = '1.0',ext_modules = [Extension('need_for_speed', ['need_for_speed.c'])])
建立模块的命令:
python setup.py build
当我调用函数prueba时:
import need_for_speed
i = need_for_speed.prueba()
python会停止运行而不打印或不返回任何内容,但是如果在“ prueba”函数中将名为“ poblacion”的数组修改为只有4个元素,它将完美运行,返回1并打印“ codigo 1212”。
我正在使用Windows BTW。
最佳答案
可能是stack overflow。
让我们看看您的结构假设它们仅占用单个成员的大小(忽略填充等)的大小:SKU
:7双打和130个字符-> 7 * 8字节+ 130字节-> 186字节Aptitud
:4倍-> 4 * 8字节-> 32字节Cromosoma
:2个整数,1个Aptitud和2000 SKU-> 2 * 4字节+ 32字节+ 2000 * 186字节-> 372040字节
因此,Chromosoma
的一个实例将花费〜370kB。然后您创建其中的5/6;一个带有Cromosoma a;
,一个用于数组中的每个插槽:4/5。
一个典型的堆栈只有几兆字节。使用6 * 370kB〜2.1MB,耗尽堆栈至少是合理的。例如,默认情况下,MSVC(Windows Visual Studio C / C ++编译器)仅使用1 MB。假设它无法使用大小为5的数组,但可以使用大小为4的数组,则看来您拥有约2 MB的堆栈。
为避免此问题,您可以增加堆栈大小(具体取决于编译器)。但是,当您需要更多的Chromosoma
或更改SKU
的数量时,增加堆栈大小将再次导致问题。
另一种选择(可能比增加堆栈大小更好)是在堆上分配所有大数组。例如,您可以在堆上分配poblacion
-和/或使Chromosoma.genes
成为指向SKU
数组的指针。