C++指针配合new初始化动态多维数组的作用域及段错误问题
问题根因
段错误核心原因是指针传参时值传递的作用域问题,叠加代码多处笔误,具体问题点:
init方法的入参double** array是值传递,函数内部给array赋值时,修改的是函数栈上的临时副本,无法修改BaseClass成员变量array的实际值。init执行结束后临时变量销毁,申请的内存地址没有传出,BaseClass::array始终是初始值nullptr,后续dump访问空指针直接触发段错误。- 代码存在多处变量名笔误:
init入参命名为darray,函数内却操作未定义的array;循环条件错写为s < rows、a < cols;元素赋值时使用未定义的data[i][j]。 dump方法实现时未加UtilClass::类作用域限定符,实际定义的是全局函数,不属于类成员。BaseClass.h中include指令缺失#前缀,无法正常编译。- 类成员方法默认访问权限为
private,未显式声明为public的话,外部无法调用init和dump。 - 原始代码未做内存释放逻辑,会造成内存泄漏。
修复方案
要让函数内部修改外部的指针,将入参改为指针的引用即可,同时修正所有笔误和访问权限、内存释放问题。
修正头文件
// BaseClass.h #pragma once #include "UtilClass.h" class BaseClass { public: UtilClass* util{nullptr}; double** array{nullptr}; BaseClass(); ~BaseClass(); };
// UtilClass.h #pragma once #include <iostream> class UtilClass { public: // 入参加&改为引用传递,才能修改外部传入的指针 void init(double**& array, int rows, int cols); void dump(double** array, int rows, int cols); void release(double**& array, int rows); };
修正实现代码
// BaseClass.cpp #include "BaseClass.h" BaseClass::BaseClass() { util = new UtilClass(); util->init(array, 4, 6); util->dump(array, 4, 6); } BaseClass::~BaseClass() { util->release(array, 4); delete util; }
// UtilClass.cpp #include "UtilClass.h" void UtilClass::init(double **&array, int rows, int cols) { int i,j; array = new double*[rows]; for (i = 0; i < rows; i++) array[i] = new double[cols]; // 修正所有变量名笔误 for (i = 0; i < rows; i++) for (j = 0; j < cols; j++) { array[i][j] = 1; std::cout << "初始化数组元素: " << array[i][j] << std::endl; } } // 补全类作用域限定符,修正循环花括号缺失问题 void UtilClass::dump(double** array, int rows, int cols) { int i, j; for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { std::cout << array[i][j] << " "; } std::cout << std::endl; } } // 新增内存释放方法避免泄漏 void UtilClass::release(double**& array, int rows) { if (!array) return; for (int i = 0; i < rows; i++) { delete[] array[i]; } delete[] array; array = nullptr; }
优化建议
如果不需要兼容C风格接口,优先使用C++标准库容器管理动态数组,从根源避免指针操作错误:
- 二维数组直接用
std::vector<std::vector<double>>定义,初始化时传入行列参数即可,容器自动管理内存分配和释放,不会出现值传递修改失效的问题。 - 如果追求内存连续性和访问性能,可以用一维数组模拟二维结构,下标换算为
i * cols + j,缓存命中率远高于指针套指针的分段存储结构。
内容的提问来源于stack exchange,提问作者Sensei
相关产品推荐
相关产品推荐

