购物清单程序动态内存分配异常:malloc返回NULL导致崩溃求助
购物清单程序动态内存分配问题解决
核心错误分析
你的代码存在三个致命错误,直接导致内存分配失败或程序崩溃:
内存分配类型完全错误
memoryAllocator函数中,你为struct ShoppingList类型分配内存,但实际需要分配的是struct GroceryItem数组(因为ShoppingList的itemList成员是指向GroceryItem的指针)。错误的类型大小计算会导致内存空间不足或分配错误的内存块。函数参数传递类型不匹配
在addItem中调用memoryAllocator时,你传入的是list->itemList(struct GroceryItem*类型),但函数期望的是struct ShoppingList**类型,这会导致指针地址混乱,realloc无法正确识别原有内存块。内存分配结果判断逻辑颠倒
代码中当temp != NULL(内存分配成功)时,反而输出错误并返回0终止流程;而分配失败(temp == NULL)时却认为成功,这完全搞反了判断逻辑。
修正后的关键代码
1. 修正memoryAllocator函数
// 修改函数参数类型为struct GroceryItem**,匹配itemList的类型 int memoryAllocator(struct GroceryItem** ListInMemory, int length) { struct GroceryItem* temp; if (length == 0) { // 分配1个GroceryItem大小的内存块 temp = (struct GroceryItem*)calloc(1, sizeof(struct GroceryItem)); } else { // 重新分配length+1个GroceryItem大小的内存块 temp = (struct GroceryItem*)realloc(*ListInMemory, (length + 1) * sizeof(struct GroceryItem)); } // 正确判断:temp为NULL则分配失败 if (temp == NULL) { printf("内存分配失败,请重试\n"); return 0; } else { *ListInMemory = temp; return 1; } }
2. 修正addItem中的调用方式
void addItem(struct ShoppingList* list) { int error = 0; // 传入itemList的地址,类型为struct GroceryItem** error = memoryAllocator(&list->itemList, list->length); if (error == 0) return; enterProductName(list); negativeCheck(list); enterUnit(list); printf("商品已添加!\n\n"); list->length = list->length + 1; return; }
3. 其他补充修正
saveList函数中free内存后,需要将itemList置为NULL,避免野指针:
void saveList(struct ShoppingList *list) { free(list->itemList); list->itemList = NULL; list->length = 0; }
itemDeleter函数中,删除元素后可以选择重新分配内存缩小空间(可选优化):
void itemDeleter(struct ShoppingList* list, int deleteThis) { int idx = deleteThis - 1; if (idx < 0 || idx >= list->length) return; for (int i = idx; i < list->length - 1; i++) { list->itemList[i] = list->itemList[i + 1]; } list->length--; // 可选:缩小内存空间,避免浪费 struct GroceryItem* temp = realloc(list->itemList, list->length * sizeof(struct GroceryItem)); if (temp != NULL) { list->itemList = temp; } }
测试验证
修正后,首次添加商品时calloc会分配1个GroceryItem的内存,后续添加时realloc会扩展内存到length+1个元素,内存分配成功判断逻辑正确,不会再触发错误终止或空指针崩溃。
内容的提问来源于stack exchange,提问作者Ted Boman
相关产品推荐
相关产品推荐

