我有一些代码来创建一个新结构并为结构数组分配一些空间。最初,我在数组上为1个结构分配空间:
static int datasetCount = 0;
int datasetgroup_new(DatasetGroup *dg char *id){
dg->id = id;
// Allocate space for a single dataset to start with
dg->datasets = (Dataset *) malloc(sizeof(Dataset));
return 0;
}
然后我有一个函数将另一个结构('数据集')添加到包含该数组的结构中。在函数结束时,我重新分配数组以提供另一个空间:
void datasetgroup_add(DatasetGroup *dg, string filePath){
// Create the dataset
Dataset ds;
dataset_new(&ds, filePath);
// Copy the dataset to the dataset array
dg->datasets[datasetCount] = ds;
// Increment the dataset counter
datasetCount++;
//Grow the array
dg->datasets = (Dataset *)realloc(dg->datasets, sizeof(Dataset) * (datasetCount + 1));
}
我继续阅读暗示在现代C中你不需要做这样的事情的事情。 我可能错了......这样做是否更现代/更正确?
编辑:
很抱歉,为了清楚我没有使用C ++类型,我为string
创建了一个typedef:
typedef char* string;
答案 0 :(得分:3)
正如前面提到的here在现代C(C11)标准中没有任何内容,但您可以使用像Glib这样的库来简化内存管理,或者您可以使用它的数据结构,如{{3 }}。
如果您使用visual studio,您可以在其中找到一些非标准功能。
要在linux中更多指定,这些函数只是brk()
系统调用的包装,它们都在用户空间中进行内存管理,它们的速度和效率取决于它们的算法,例如GNU C Library获得一些空间在堆中然后为你管理它,所以不是所有的realloc()
调用都会结束brk()
系统调用,所以不要过多担心它们的效率。您可以使用array来查看内存分析。
答案 1 :(得分:3)
我不清楚你对现代C的意思,但是我想提到代码中有两件事。
realloc
的使用方式错误。如果它失败并返回NULL,那么原始内存将被泄露。例如,请参阅Dynamic arrays: using realloc() without memory leaks
增长内存的逻辑调用realloc
,因此每次添加时都会调用内存(即调用datasetgroup_add
)。它将动态数组的大小/容量增加一个。这可能不太理想。增长这种记忆的常用习惯是在容量变满时将其加倍。这样,在所有调用中,内存分配的成本为amortized(What is amortized analysis of algorithms?)。