You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

循环赋值失效:动态数组无法存储TelemetryData测量值问题求助

动态数组赋值异常的问题修复

问题描述

我创建了初始大小为1的float数组,想在for循环中从telemetryArray取数据存入:首次迭代存下标0(counter初始为0),counter自增后用realloc以counter+1为新大小扩容。但数据无法正常存入数组——telemetryArray的数据正常(已临时打印验证),但赋值后sensorArray里的数据不对。排序和后续打印逻辑本身没问题,仅赋值环节出错,且必须每次循环动态扩容。

代码中的核心错误

  1. 内存分配的类型与大小不匹配
    • sensorArray是float*类型,但realloc时强制转换为(int*),同时用sizeof(int)计算内存大小。这会导致分配的内存空间大小错误(即使int和float字节数相同,类型转换也会破坏指针的类型语义,后续访问会出现数据异常)。
  2. 调试打印的索引错误
    • 临时打印时用了外层循环的i作为sensorArray的索引,这完全不符合逻辑。应该用刚完成赋值的索引(比如counter,赋值后还未自增时)来查看存入的数据。
  3. qsort的参数错误
    • qsort的第三个参数传了sizeof(int),但数组元素是float类型,参数不匹配会导致排序逻辑出错。
  4. 缺少内存分配失败检查
    • malloc和realloc都可能返回空指针,未做检查会触发空指针访问崩溃。
  5. 未处理除零错误
    • 当没有匹配到传感器数据时,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 19:35:05