为接收结构体的函数分配正确内存:动态数据库异常排查
问题分析与代码修正
代码中的核心错误
- scanf参数错误:main函数中
scanf("%d", newSize2);未传入变量地址,会触发非法内存访问,直接导致程序崩溃,应改为scanf("%d", &newSize2);。 - 内存分配计算错误:
newDatabase函数里malloc(sizeof(database)*newSize),database是指针类型,sizeof(database)是指针的字节数(如4/8字节),而非product_t结构体的大小,正确写法是malloc(sizeof(product_t)*newSize)。 - 未保存新数据库指针:调用
newDatabase后,没有将返回的新指针赋值给database,导致新创建的数据库地址丢失,同时需要更新dbSize为新的大小。 - 初始化不完整且存在无效操作:仅初始化了第一个结构体元素,其余元素的
price和product为随机值;同时对newdatabase->product的malloc、赋值NULL、free操作完全冗余,无实际意义。
修正后的完整代码
#include <stdio.h> #include <string.h> #include <stdlib.h> typedef struct _product_t { char *product; float price; } product_t; product_t *newDatabase(product_t *database, int *dbSize, int newSize) { // 释放旧数据库内存 free(database); // 分配新数据库内存,使用结构体大小计算 product_t *newdatabase = (product_t*)malloc(sizeof(product_t)*newSize); if (newdatabase == NULL) { printf("内存分配失败\n"); *dbSize = 0; return NULL; } // 初始化所有元素 for (int i = 0; i < newSize; i++) { newdatabase[i].product = NULL; newdatabase[i].price = -1.0f; } // 更新数据库大小 *dbSize = newSize; return newdatabase; } int main(void) { product_t *database = NULL; int dbSize = 0; char cmd; do{ printf("Command? "); scanf(" %c", &cmd); switch (cmd) { case 'q': printf("Bye!"); break; case 'n': printf("Size? "); int newSize2 = 0; // 传入变量地址 scanf("%d", &newSize2); // 接收新数据库指针 database = newDatabase(database, &dbSize, newSize2); break; default: printf("Unknown command '%c'\n",cmd); } }while(cmd != 'q'); // 程序结束前释放数据库内存,避免泄漏 free(database); return 0; }
额外优化说明
- 增加了内存分配失败的判断,避免空指针操作。
- 程序结束时手动释放数据库内存,避免内存泄漏。
- 修正了原代码中"Unkown"的拼写错误为"Unknown"。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

