循环赋值失效:动态数组无法存储TelemetryData测量值问题求助
动态数组赋值异常的问题修复
问题描述
我创建了初始大小为1的float数组,想在for循环中从telemetryArray取数据存入:首次迭代存下标0(counter初始为0),counter自增后用realloc以counter+1为新大小扩容。但数据无法正常存入数组——telemetryArray的数据正常(已临时打印验证),但赋值后sensorArray里的数据不对。排序和后续打印逻辑本身没问题,仅赋值环节出错,且必须每次循环动态扩容。
代码中的核心错误
- 内存分配的类型与大小不匹配
- sensorArray是
float*类型,但realloc时强制转换为(int*),同时用sizeof(int)计算内存大小。这会导致分配的内存空间大小错误(即使int和float字节数相同,类型转换也会破坏指针的类型语义,后续访问会出现数据异常)。
- sensorArray是
- 调试打印的索引错误
- 临时打印时用了外层循环的
i作为sensorArray的索引,这完全不符合逻辑。应该用刚完成赋值的索引(比如counter,赋值后还未自增时)来查看存入的数据。
- 临时打印时用了外层循环的
- qsort的参数错误
- qsort的第三个参数传了
sizeof(int),但数组元素是float类型,参数不匹配会导致排序逻辑出错。
- qsort的第三个参数传了
- 缺少内存分配失败检查
- malloc和realloc都可能返回空指针,未做检查会触发空指针访问崩溃。
- 未处理除零错误
- 当没有匹配到传感器数据时,counter为0,计算平均值会触发除零错误。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // 假设TelemetryData结构体定义如下 typedef struct { char sensorType[20]; float measurement; } TelemetryData; // 适配float类型的qsort比较函数 int compare(const void* a, const void* b) { float fa = *(const float*)a; float fb = *(const float*)b; return (fa > fb) - (fa < fb); // 升序排序逻辑 } void filterBySensorTypeAvg(TelemetryData* telemetryArray, int arraySize) { char sensorType[20]; int counter = 0; float sum = 0, avg = 0; float* sensorArray = malloc(1 * sizeof(float)); if (!sensorArray) { // 检查malloc是否成功 perror("malloc failed"); return; } printf("Enter the sensor type to filter: "); #if (_MSC_VER > 1600) scanf_s("%19s", sensorType, (unsigned)(sizeof(sensorType) / sizeof(sensorType[0]))); #else scanf("%19s", sensorType); #endif printf("Telemetry Data for Sensor Type '%s':\n", sensorType); for (int i = 0; i < arraySize; ++i) { if (strcmp(telemetryArray[i].sensorType, sensorType) == 0) { sum += telemetryArray[i].measurement; sensorArray[counter] = telemetryArray[i].measurement; // 打印刚存入的数组元素,索引正确 printf("%.2f %.2f\n", telemetryArray[i].measurement, sensorArray[counter]); counter++; // 修正realloc的类型、大小,同时检查是否成功 float* temp = realloc(sensorArray, (counter + 1) * sizeof(float)); if (!temp) { perror("realloc failed"); free(sensorArray); // 失败时释放已分配内存 return; } sensorArray = temp; if (counter > 20) { break; } } } // 处理无匹配数据的情况,避免除零 if (counter == 0) { printf("No data found for sensor type '%s'\n", sensorType); free(sensorArray); return; } avg = sum / counter; printf("The Average %s is %.2f from a total of %.2f\n", sensorType, avg, sum); // 修正qsort的元素大小参数 qsort(sensorArray, counter, sizeof(float), compare); for (int i = 0; i < counter; i++) { printf("%.2f, ", sensorArray[i]); } printf("\n"); printf("\nArraySize: %i\n", arraySize); free(sensorArray); // 释放动态内存,避免泄漏 }
关键修改说明
- 修正内存分配逻辑:
realloc不再强制类型转换,改用float*接收返回值,同时用sizeof(float)计算元素大小,确保内存分配与数组类型匹配。 - 修复打印索引:直接使用赋值时的
counter索引打印刚存入的数据,确保调试信息准确。 - 增加内存安全检查:对malloc和realloc的返回值做非空检查,失败时释放已分配内存并退出,避免崩溃和内存泄漏。
- 规避除零错误:判断counter是否为0,无匹配数据时直接提示并退出,避免平均值计算触发除零异常。
- 修正排序参数:将qsort的元素大小改为
sizeof(float),匹配数组元素类型,确保排序逻辑正常。 - 释放动态内存:函数结束前释放sensorArray,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Nathan
相关产品推荐
相关产品推荐

