如何计算结构体realloc后的内存及当前记录数量
问题解决:动态扩容结构体数组时的记录数计算问题
核心问题:C语言中,无法通过指针本身获取它指向的动态内存块的元素数量。你原来的sizeof(theseRecords)/sizeof(record)之所以错误,是因为theseRecords是指针变量,sizeof(theseRecords)得到的是指针的字节大小(比如64位系统是8字节),和它指向的内存块总大小无关。
必须手动维护一个计数器来记录当前的记录总数,同时还要解决指针传递的问题(realloc可能改变内存地址,需要同步到主函数的指针变量)。
具体修改步骤
1. 在主函数中添加记录计数器
在main函数里新增变量记录当前已有的记录数(初始值为1,因为createFirstRecord已经创建了第一个记录):
int main() { record * theRecords; unsigned int recordCount = 1; // 初始记录数为1 char response; theRecords = createFirstRecord(); if (theRecords == NULL) { printf("\nERROR! Out of memory!"); return 0; } showTopMenu(); scanf(" %c", &response); response = toupper(response); while (response != 'Q') { switch (response) { case 'A': // 传入指针的地址和计数器的地址 if (!addRecord(&theRecords, &recordCount)) { // 可在这里处理内存分配失败的后续逻辑 } break; case 'E': editRecord(theRecords, recordCount); // 若editRecord需要记录数,同步传入 break; } showTopMenu(); scanf(" %c", &response); response = toupper(response); } return 0; }
2. 修改addRecord函数的参数与逻辑
将函数参数改为二级指针(用于修改主函数中的指针变量)和计数器的指针(用于更新记录数),直接使用传入的计数器计算扩容后的内存大小:
unsigned int addRecord(record ** theseRecords, unsigned int * recordCount) { record * tempRecord; // 扩容到当前记录数+1的大小 tempRecord = (record *)realloc(*theseRecords, (*recordCount + 1) * sizeof(record)); if (tempRecord == NULL) { printf("\nERROR! Out of memory!\n"); return 0; } // 更新主函数中的指针 *theseRecords = tempRecord; // 记录数加1 (*recordCount)++; printf("\n\tAdd Record\n"); // 填充新的记录(指向扩容后的最后一个元素) fillRecord(*theseRecords + (*recordCount - 1)); return 1; }
关键说明
- 用二级指针的原因:
realloc可能返回新的内存地址,直接传递指针的话,函数内部的修改不会影响主函数中的theRecords变量,必须通过指针的指针修改原变量。 - 手动维护计数器的原因:C标准库没有提供获取动态分配内存大小的接口,必须自己跟踪已分配的元素数量。
- 填充新记录时要指向最后一个元素,避免覆盖已有的第一个记录。
内容的提问来源于stack exchange,提问作者Stuart
相关产品推荐
相关产品推荐

