C++中返回二维数组时如何避免Segmentation Fault?
问题描述
这是一门C++入门课程的作业任务:在二维数组matrix中查找两个数之和等于给定值search_sum的所有组合,将找到的加数组合以{startRow,startColumn,endRow,endColumn}的形式存入summations数组,最终返回该数组。
我尝试用语句summations[*sums_found]={startRow, column, endRow, column};给已分配的内存赋值时,触发了“too many assignments”和段错误(Segmentation Fault)。移除这条赋值语句后运行代码,还是会出现段错误。
我的困惑:
- 这段代码是用来分配内存写入数据的,为什么会触发和只读相关的段错误?
- 该如何正确为
summations数组赋值? - 需要重点学习哪些C++知识点来解决这类问题?
当前代码如下:
// Parameters: // - matrix: a two-dimension integer array // - matrix_size: a two-element size_t array storing sizes of matrix // - search_sum: the integer value for which the function seeks sums // - sums_found: an OUTPUT PARAMETER pointing to a size_t // const size_t** FindSum(const int** matrix, const size_t* matrix_size, int search_sum, size_t* sums_found) { *sums_found = 0; // init sums found to 0 size_t summations_size = 2; // start assuming no more than 2 summations // build structure to hold all found summations size_t** summations = new size_t*[summations_size]; switch (search_sum) { case -92:{ //column search for(size_t column = 0; column < matrix_size[1]; column++){ for(size_t startRow = 0; startRow < matrix_size[0]; startRow++){ for(size_t endRow = 0; endRow < matrix_size[0]; endRow++){ int j = matrix[startRow][column]; int k = matrix[endRow][column]; int sum = j + k; if(sum = search_sum){ summations[*sums_found] = new size_t[kIndices_size]; // only done when summation is found *sums_found++; } } } } } break; case 60:{ //row search for(size_t row = 0; row < matrix_size[0]; row++){ for(size_t startColumn = 0; startColumn < matrix_size[1]; startColumn++){ for(size_t endColumn = 0; endColumn < matrix_size[1]; endColumn++){ int j = matrix[row][startColumn]; int k = matrix[row][endColumn]; int sum = j + k; if(sum = search_sum){ summations[*sums_found] = new size_t[kIndices_size]; // only done when summation is found *sums_found++; } } } } } break; case 1203:{ //desc/ascending diagonal } break; case 412:{ //single entry } break; default:{ //large array } break; } return const_cast<const size_t**>(summations); }
问题分析与解决
1. 段错误的触发原因
你的代码里有几个致命错误直接导致了段错误:
- 赋值代替比较:
if(sum = search_sum)是赋值操作,不是比较逻辑。这会把search_sum的值强制赋给sum,条件永远为真(除非search_sum是0),导致*sums_found不断递增,很快超过初始化的summations_size=2,访问summations[*sums_found]时直接越界,触发段错误。 - 未定义变量
kIndices_size:代码中使用了kIndices_size但从未定义或初始化,分配内存时会用随机值,可能分配异常大的内存导致耗尽,或者分配后访问越界。 - 内存越界访问:即使
kIndices_size是正确值(比如4,对应每个组合的4个坐标),当找到的组合数超过summations_size=2时,summations[*sums_found]会访问超出new size_t*[summations_size]分配的内存范围,直接触发段错误。
2. 正确为summations数组赋值的方法
按以下步骤修改代码:
- 先定义
kIndices_size为4,因为每个组合需要存储{startRow, startColumn, endRow, endColumn}四个值。 - 把条件判断里的
=改成==,确保是比较操作。 - 每次找到符合条件的组合时,先检查当前找到的数量是否超过
summations_size,如果超过就扩容(重新分配更大的数组,拷贝旧数据后替换原数组)。 - 分配内存后,逐个给数组元素赋值(C++中不能直接用大括号给动态分配的数组赋值)。
修改后的示例片段(以column search为例):
// 先定义常量,明确每个组合的元素数量 const size_t kIndices_size = 4; // ... case -92:{ //column search for(size_t column = 0; column < matrix_size[1]; column++){ for(size_t startRow = 0; startRow < matrix_size[0]; startRow++){ for(size_t endRow = 0; endRow < matrix_size[0]; endRow++){ int j = matrix[startRow][column]; int k = matrix[endRow][column]; int sum = j + k; if(sum == search_sum){ // 修正为比较运算符 // 检查是否需要扩容 if (*sums_found >= summations_size) { size_t new_size = summations_size * 2; size_t** new_summations = new size_t*[new_size]; // 拷贝旧数据到新数组 for (size_t i = 0; i < summations_size; i++) { new_summations[i] = summations[i]; } // 释放旧数组内存 delete[] summations; summations = new_summations; summations_size = new_size; } // 分配内存并逐个赋值 summations[*sums_found] = new size_t[kIndices_size]; summations[*sums_found][0] = startRow; summations[*sums_found][1] = column; summations[*sums_found][2] = endRow; summations[*sums_found][3] = column; (*sums_found)++; // 加括号确保先取值再递增 } } } } } break;
3. 需要重点学习的C++知识点
- 动态内存管理:掌握
new/delete的用法,理解动态数组的创建、扩容与内存释放逻辑,清楚内存越界的危害。 - 运算符区分:严格区分赋值运算符
=和比较运算符==,避免这类低级逻辑错误。 - 多维数组结构:理解二维动态数组(指针的指针)的内存结构,学会正确访问和操作其中的元素。
- 错误排查技巧:学会用调试工具(如gdb)定位段错误的根源,熟悉段错误的常见触发场景(内存越界、访问空指针、未初始化变量等)。
- 变量定义规范:确保所有使用的变量都已正确定义、初始化,避免未定义行为。
内容的提问来源于stack exchange,提问作者David Wamai
相关产品推荐
相关产品推荐

