C++提取矩阵左上角子矩阵触发SIGSEGV错误问题排查
错误原因定位
- 直接触发段错误的原因是子矩阵维度分配错误:你需要提取的左上角子矩阵大小为
dim/2 * dim/2,但代码中错误写成了dim/4。你测试用的dim=2时,dim/4=0,相当于申请了长度为0的指针数组,后续访问tl[i][j]时直接访问了未被映射的内存区域,对应Valgrind输出的Access not within mapped region at address 0x0报错。 - 即使使用更大的dim测试也会出错:比如dim=4时,
dim/4=1,申请的子矩阵大小为1x1,但你要赋值的i、j范围是小于dim/2=2,会访问到tl[1][1],还是会触发数组越界。 - 存在冗余逻辑和内存泄漏问题:当前遍历了整个原矩阵,实际只需要遍历左上角子矩阵范围即可;函数内申请的
tl矩阵没有释放逻辑,也没有作为返回值/输出参数带出,没有实际业务作用。
修正代码示例
template<typename T> T** split_tl(T **matrice, unsigned int dim){ // 新增边界判断:dim为1或奇数时不支持拆分 if(dim == 1 || dim % 2 != 0){ return nullptr; } unsigned int sub_dim = dim / 2; // 正确分配子矩阵内存 T **tl = new T*[sub_dim]; for(unsigned int i = 0; i < sub_dim; ++i){ tl[i] = new T[sub_dim]; } // 仅遍历子矩阵对应范围即可 for(unsigned int i = 0; i < sub_dim; ++i){ for(unsigned int j = 0; j < sub_dim; ++j){ tl[i][j] = matrice[i][j]; } } return tl; }
// 测试与内存释放示例 int main(){ const unsigned int dim = 2; int **matrice = new int*[dim]; for(unsigned int i = 0; i < dim; ++i){ matrice[i] = new int[dim]; } for(unsigned int i = 0; i < dim; ++i){ for(unsigned int j = 0; j < dim; ++j){ matrice[i][j] = i + j; } } int** tl_matrix = split_tl(matrice, dim); // 打印子矩阵验证结果 if(tl_matrix != nullptr){ for(unsigned int i = 0; i < dim/2; ++i){ for(unsigned int j = 0; j < dim/2; ++j){ std::cout << tl_matrix[i][j] << " "; } std::cout << std::endl; } // 释放子矩阵内存 for(unsigned int i = 0; i < dim/2; ++i){ delete[] tl_matrix[i]; } delete[] tl_matrix; } // 释放原矩阵内存 for(unsigned int i = 0; i < dim; ++i){ delete[] matrice[i]; } delete[] matrice; return 0; }
内容的提问来源于stack exchange,提问作者Samuele Pipitone
相关产品推荐
相关产品推荐

