使用PLplot绘制颜色图时触发Segmentation Fault错误求助
Segmentation Fault排查与修复:PLplot颜色图绘制程序
核心错误原因及修复
1. 主函数语法错误
主函数中存在无效代码Here is where the error pops up,会导致编译失败,直接删除该行即可。
2. 未检查数据是否为空
createColourMap函数直接访问data[0].size(),若readData返回空数据(如文件不存在、文件为空),data.size() == 0时data[0]会触发数组越界,引发segfault。
修复:
在使用数据前添加空校验:
void createColourMap(const std::vector<std::vector<int> >& data) { if (data.empty()) { std::cerr << "Error: No data to plot." << std::endl; return; } int rows = data.size(); int col = data[0].size(); // 后续代码 }
3. 二维数组z索引越界
代码中z按列数分配指针数组PLFLT **z = new PLFLT*[col];,但赋值时使用z[i][j] = data[i][j],i的范围是0到col-1,而data的行数为rows,当col > rows时,data[i]会访问超出data的行范围,触发越界。
修复:
z的结构需匹配data的行优先结构:
// 按行数分配z的指针数组 PLFLT **z = new PLFLT*[rows]; for (int i = 0; i < rows; ++i) { z[i] = new PLFLT[col]; for (int j = 0; j < col; ++j) { z[i][j] = data[i][j]; // 行i、列j,与data结构一致 } }
4. std::min/std::max用法错误
std::min(z, z + (rows * col))是错误用法:z是二维指针数组,std::min会比较指针地址而非元素值,且z + rows*col超出z的实际范围,解引用后访问非法内存。
修复:
遍历二维数组计算z的最小/最大值:
PLFLT zmin = z[0][0]; PLFLT zmax = z[0][0]; for (int i = 0; i < rows; ++i) { for (int j = 0; j < col; ++j) { if (z[i][j] < zmin) zmin = z[i][j]; if (z[i][j] > zmax) zmax = z[i][j]; } }
5. PLplot imagefr参数不匹配
imagefr函数中nx是x方向点数(列数),ny是y方向点数(行数),原代码传入的rows和col顺序颠倒,导致绘图时内存访问异常。
修复:
pls->imagefr(z, col, rows, xmin, xmax, ymin, ymax, zmin, zmax, 0, 0, 0, 0);
6. 内存泄漏问题
创建的plstream和z数组未释放,虽不直接引发segfault,但会导致内存泄漏,需补充释放逻辑:
修复:
在函数末尾添加:
// 释放z数组 for (int i = 0; i < rows; ++i) { delete[] z[i]; } delete[] z; // 释放plstream对象 delete pls;
修正后的完整代码示例
头文件引用
#include <iostream> #include <string.h> #include <plplot/plstream.h> #include <plplot/plplot.h> #include <fstream> #include <vector> #include <sstream> using namespace std; #define NSIZE 101
读取数据函数
// 读取文本文件数据 std::vector<std::vector<int> > readData(const std::string& filename) { std::vector<std::vector<int> > data; std::ifstream file(filename.c_str()); std::string line; if (!file.is_open()) { std::cerr << "Unable to open file " << filename << std::endl; exit(1); } while (std::getline(file, line)) { std::istringstream iss(line); std::vector<int> row; int value; while (iss >> value) { row.push_back(value); } if(!row.empty()) { data.push_back(row); } } file.close(); return data; }
绘制颜色图函数
void createColourMap(const std::vector<std::vector<int> >& data) { if (data.empty()) { std::cerr << "Error: No data to plot." << std::endl; return; } int rows = data.size(); int col = data[0].size(); plstream *pls = new plstream(); pls->sdev("xwin"); pls->init(); pls->env(0.0, rows, 0.0, col, 1, -1); pls->lab("X", "Y", "Colour Map Example"); // 按行分配二维数组,匹配data结构 PLFLT **z = new PLFLT*[rows]; for (int i = 0; i < rows; ++i) { z[i] = new PLFLT[col]; for (int j = 0; j < col; ++j) { z[i][j] = data[i][j]; } } pls->scmap1l(true, 256, NULL, NULL, NULL, NULL); PLFLT xmin = 0.0, xmax = static_cast<PLFLT>(rows - 1); PLFLT ymin = 0.0, ymax = static_cast<PLFLT>(col - 1); // 计算z的最小最大值 PLFLT zmin = z[0][0]; PLFLT zmax = z[0][0]; for (int i = 0; i < rows; ++i) { for (int j = 0; j < col; ++j) { if (z[i][j] < zmin) zmin = z[i][j]; if (z[i][j] > zmax) zmax = z[i][j]; } } pls->col0(1); // 修正imagefr参数顺序:nx为列数,ny为行数 pls->imagefr(z, col, rows, xmin, xmax, ymin, ymax, zmin, zmax, 0, 0, 0, 0); // 释放内存 for (int i = 0; i < rows; ++i) { delete[] z[i]; } delete[] z; delete pls; }
主函数
int main( int argc, char *argv[] ) { std::vector<std::vector<int> > data; data = readData("Test.txt"); createColourMap(data); return 0; }
额外排查建议
- 确认Test.txt格式:每行数值数量一致,避免data中各行列数不同引发索引越界。
- 使用调试工具定位问题:编译时添加
-g参数,通过gdb运行程序,触发错误后用bt命令查看调用栈,明确错误代码行。
内容的提问来源于stack exchange,提问作者sunboy
相关产品推荐
相关产品推荐

