>假设我有两个结构,其中一个扩展了另一个结构(如下所示)。从现有结构创建扩展结构时处理内存的正确过程是什么?是否应该再次要求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);
}
您的结构扩展机制类似于基元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
函数应像free
和C++ delete
运算符一样优雅地忽略NULL
指针。
为了保持一致性,您还将分离delete_grid
和finalize_grid
函数,以便从finalize_super_grid
调用finalize_grid
。 对于这个简单的示例来说,它并不是绝对必要的,但如果您实例化未分配Grid
结构(使用静态或自动存储或嵌入更复杂的上层结构),则可能会很方便。
这种穷人的C++阶级制度很快就会显示出它的局限性。 您可以考虑直接使用C++。