结构体数组复制失败:memcpy无效致程序崩溃或无响应
结构体数组复制与程序崩溃问题的解决建议
核心问题分析与修复步骤
1. 错误计算有效银行数量
代码中activeBanks = sizeof(bank);完全错误:bank是指针,sizeof(bank)得到的是指针本身的字节数(通常为4或8),而非数组元素个数。
修复:
替换为计算defaultBankData的实际元素数量:
activeBanks = sizeof(defaultBankData) / sizeof(defaultBankData[0]);
如果需要将defaultBankData重复填充到bank数组(填满10个位置),则需要循环复制:
int defaultBankCount = sizeof(defaultBankData) / sizeof(defaultBankData[0]); // 循环复制defaultBankData到bank数组,直到填满totalBanks个位置 for (int i = 0; i < totalBanks; ) { int copyCount = (totalBanks - i) > defaultBankCount ? defaultBankCount : (totalBanks - i); memcpy(&bank[i], defaultBankData, copyCount * sizeof(Bank)); i += copyCount; } activeBanks = totalBanks; // 如果要使用全部10个位置
2. 非法释放指针导致野指针崩溃
GenerateBuyingSellingPrice函数中调用free(bank);,但bank是在main函数中分配的内存。释放后main中后续若再访问bank会触发野指针错误,导致程序崩溃。
修复:
删除GenerateBuyingSellingPrice中的free(bank);,将内存释放逻辑移到main函数末尾(退出前):
// main函数末尾,do-while循环结束后添加 free(bank);
3. ValidateDate函数的数组越界问题
当前代码在查找月份时,循环结束后i的值为12,此时访问daysInMonth[i-1]会取到daysInMonth[11](12月的天数),无论用户输入的是哪个月份,导致日期验证错误。
修复:
找到匹配月份时记录索引并退出循环:
int ValidateDate(Date *userDate) { const int MAX_YR = 9999, MIN_YR = 1900; int validMonth = 0, validDay = 0, validyear = 0, result = 0; int daysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; char* months[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; int monthIndex = -1; // 闰年处理 if(userDate->yyyy % 400 == 0 || (userDate->yyyy % 100 != 0 && userDate->yyyy % 4 == 0)) { daysInMonth[1] = 29; } // 查找匹配的月份并记录索引 for(int i = 0; i < 12; i++) { if(!strcmp(userDate->mmm, months[i])) { validMonth = 1; monthIndex = i; break; // 找到后立即退出循环 } } if(validMonth == 1 && monthIndex != -1) { if(userDate->dd >= 1 && userDate->dd <= daysInMonth[monthIndex]) // 补充日期下限验证 { validDay = 1; } } if(userDate->yyyy >= MIN_YR && userDate->yyyy <= MAX_YR) { validyear = 1; } if(validDay && validMonth && validyear) result = 1; return result; }
4. 文件追加写入导致读取异常
SaveFXSummary使用"ab"模式追加写入,多次执行选项1会导致文件中存在多组数据块,后续读取时会出错。
修复:
改为使用"wb"模式覆盖写入,确保每次只保存最新的一组数据:
file = fopen(fileName, "wb");
5. GenerateBuyingSellingPrice中的循环逻辑错误
内层循环for(int k = 0; k < PRICES; k+=2)会导致只执行一次循环(因为PRICES=2),但逻辑上应该直接为买入价和卖出价赋值,无需步进2。可以简化为:
for(int j = 0; j < CURRENCIES; j++) { float buyPrice = GetPrices(); bank[i].currencyPrice[j][0] = buyPrice; // 买入价 bank[i].currencyPrice[j][1] = buyPrice + SPREAD; // 卖出价 }
修复后的核心流程验证
- 启动程序后,
bank数组会被正确填充defaultBankData的重复数据(或全部4个默认银行)。 - 选择选项1输入有效日期后,
GenerateBuyingSellingPrice会正确为每个银行生成汇率并保存到文件。 - 选择选项2可以正常读取并显示文件中的汇率数据,不会出现崩溃或无响应。
内容的提问来源于stack exchange,提问作者Crimarco
相关产品推荐
相关产品推荐

