假设我有两个结构,其中一个结构扩展另一个结构(如下所示)。从现有结构创建扩展结构时,处理内存的正确步骤是什么?是否应该再次调用malloc用于新结构?这会将内存分配加倍吗?
typedef struct Grid {
int rows;
int cols;
int * grid;
} Grid;
typedef struct SuperGrid {
Grid;
char * property;
int id;
} SuperGrid;
static Grid * new_grid(int rows, int cols) {
Grid * grid = (Grid *)(malloc(sizeof(Grid)));
grid->rows= rows;
grid->cols= cols;
grid->grid = (int *)(calloc(rows*cols, sizeof(int)));
}
static SuperGrid * new_super_grid(int rows, int cols) {
/* What needs to happen here? */
return (SuperGrid *)new_grid(rows, cols);
}
答案 0 :(得分:3)
您的结构扩展机制类似于原始C ++类派生系统。 要实现您的目标,您需要分离结构分配和初始化:
typedef struct Grid {
int rows;
int cols;
int *grid;
} Grid;
typedef struct SuperGrid {
Grid;
char *property;
int id;
} SuperGrid;
static Grid *init_grid(Grid *grid, int rows, int cols) {
if (grid) {
grid->rows = rows;
grid->cols = cols;
grid->grid = (int *)calloc(rows * cols, sizeof(int));
}
return grid;
}
static Grid *new_grid(int rows, int cols) {
return init_grid((Grid *)malloc(sizeof(Grid)), rows, cols);
}
static SuperGrid *init_super_grid(SuperGrid *sg, int rows, int cols,
const char *property, int id) {
if (sg) {
init_grid((Grid *)sg, rows, cols);
sg->property = strdup(property);
sg->id = id;
}
return sg;
}
static SuperGrid *new_super_grid(SuperGrid *sg, int rows, int cols,
const char *property, int id) {
return init_super_grid((SuperGrid *)malloc(sizeof(SuperGrid)),
rows, cols, property, id);
}
分配器可能会失败,并在内存分配失败时返回NULL
。您可能希望它们以更明确的方式失败,例如通过abort
以错误消息退出程序。同样,delete_xxx
函数应优雅地忽略NULL
指针free
和C ++ delete
运算符。
为了保持一致性,您还会将delete_grid
和finalize_grid
功能分开,以便从finalize_grid
拨打finalize_super_grid
。这个简单示例并不是绝对必要的,但如果您实例化未分配的Grid
结构(使用静态或自动存储或嵌入更复杂的上层结构),则可能会很方便。
这个穷人的C ++类系统很快就会显示其局限性。您可以考虑直接使用C ++。