结构扩展的内存分配

时间:2015-03-17 04:50:46

标签: c

假设我有两个结构,其中一个结构扩展另一个结构(如下所示)。从现有结构创建扩展结构时,处理内存的正确步骤是什么?是否应该再次调用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); 
}

1 个答案:

答案 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_gridfinalize_grid功能分开,以便从finalize_grid拨打finalize_super_grid。这个简单示例并不是绝对必要的,但如果您实例化未分配的Grid结构(使用静态或自动存储或嵌入更复杂的上层结构),则可能会很方便。

这个穷人的C ++类系统很快就会显示其局限性。您可以考虑直接使用C ++。