# 段错误修复说明 ## 问题定位 段错误发生在 `ECG_12LEAD_Data_Mapper` 函数的这一行: ```cpp output_channels[9][sample] = -0.5f * (lead_I + lead_II); // aVR ``` ## 根本原因 ### 1. **数组未初始化** ```cpp // 问题代码:只创建了向量,但没有设置大小 std::vector> output_channels(12); // 此时 output_channels[9] 是一个空的向量,访问 [sample] 会导致段错误 ``` ### 2. **缺少边界检查** ```cpp // 问题代码:直接访问数组元素,没有验证索引和大小 output_channels[9][sample] = value; // 可能越界 ``` ## 修复方案 ### 1. **正确初始化所有通道** ```cpp // 修复后:为所有12个通道设置正确的大小 std::vector> output_channels(12); for (int ch = 0; ch < 12; ++ch) { output_channels[ch].resize(num_samples, 0.0f); // 初始化为0 } ``` ### 2. **添加边界检查** ```cpp // 修复后:在访问数组前验证索引和大小 if (9 < output_channels.size() && 10 < output_channels.size() && 11 < output_channels.size()) { if (sample < output_channels[9].size() && sample < output_channels[10].size() && sample < output_channels[11].size()) { output_channels[9][sample] = -0.5f * (lead_I + lead_II); // aVR output_channels[10][sample] = lead_I - 0.5f * lead_II; // aVL output_channels[11][sample] = lead_II - 0.5f * lead_I; // aVF } } ``` ### 3. **验证输入数据一致性** ```cpp // 修复后:确保所有前8个通道都有相同的采样点数 for (size_t i = 1; i < 8; ++i) { if (input_channels[i].size() != num_samples) { throw std::runtime_error("Channel " + std::to_string(i) + " has different sample count: " + std::to_string(input_channels[i].size()) + " vs " + std::to_string(num_samples)); } } ``` ### 4. **验证输出数据完整性** ```cpp // 修复后:确保所有输出通道都有正确的大小 for (size_t ch = 0; ch < output_channels.size(); ++ch) { if (output_channels[ch].size() != num_samples) { throw std::runtime_error("Output channel " + std::to_string(ch) + " has incorrect size: " + std::to_string(output_channels[ch].size()) + " vs expected " + std::to_string(num_samples)); } } ``` ## 修复前后的对比 ### **修复前(有段错误风险)** ```cpp // 创建12导联输出结构 std::vector> output_channels(12); // 直接访问未初始化的通道 output_channels[9][sample] = value; // ❌ 段错误! ``` ### **修复后(安全)** ```cpp // 创建12导联输出结构,并初始化所有通道的大小 std::vector> output_channels(12); for (int ch = 0; ch < 12; ++ch) { output_channels[ch].resize(num_samples, 0.0f); // 初始化为0 } // 安全的数组访问 if (9 < output_channels.size() && sample < output_channels[9].size()) { output_channels[9][sample] = value; // ✅ 安全 } ``` ## 技术要点 ### 1. **向量初始化的重要性** - `std::vector>(12)` 只创建了12个空的向量 - 每个内部向量需要单独调用 `resize()` 设置大小 - 使用 `resize(size, default_value)` 可以同时设置大小和默认值 ### 2. **边界检查的必要性** - 即使理论上索引应该有效,也要进行边界检查 - 使用 `if` 语句验证索引和大小 - 提供清晰的错误信息,便于调试 ### 3. **数据一致性验证** - 确保所有输入通道有相同的采样点数 - 验证输出通道的完整性 - 在关键步骤添加断言或异常 ## 预防措施 ### 1. **始终初始化容器** ```cpp // 好的做法 std::vector> channels(12); for (auto& ch : channels) { ch.resize(expected_size, default_value); } ``` ### 2. **使用范围检查** ```cpp // 好的做法 if (index < container.size() && sample < container[index].size()) { container[index][sample] = value; } ``` ### 3. **添加调试信息** ```cpp // 好的做法 std::cout << "Creating " << num_channels << " channels with " << num_samples << " samples each" << std::endl; ``` ## 测试建议 1. **运行测试模式1**: 验证解析器工作正常 2. **运行测试模式2**: 测试完整的映射流程 3. **观察调试输出**: 确认所有通道都被正确初始化 4. **检查输出文件**: 验证12导联数据完整性 现在段错误应该已经被修复,程序可以安全地处理12导联心电数据了!