二维数组中的内存泄漏
Posted
技术标签:
【中文标题】二维数组中的内存泄漏【英文标题】:Memory leak in a 2D array 【发布时间】:2017-11-24 02:08:33 【问题描述】:我有一堂课:
class Land
public:
~Land() if(map != nullptr) Clean();
bool Create();
void PrintMap() const;
void Clean();
private:
int rows = 0, columns = 0;
int **map = nullptr;
bool CorrectDimensions() const;
void CreateMap();
bool FillMap();
;
bool Land::Create()
//
printf("Matrix size:\n");
if(scanf("%d %d", &(this->columns), &(this->rows) ) != 2 || !CorrectDimensions() )
return false;
CreateMap();
printf("Values:\n");
return FillMap();
void Land::CreateMap()
//
this->map = new int*[rows];
for(int column = 0; column < this->rows; column++)
map[column] = new int[this->columns];
bool Land::FillMap()
//
for(int row = 0; row < this->rows; row++)
for(int column = 0; column < this->columns; column++)
if( ! scanf("%d", &(this->map[row][column]) ) )
return false;
return true;
void Land::Clean()
//
for(int row = 0; row < this->rows; row++)
delete [] this->map[row];
delete [] this->map;
还有我的司机:
int main()
//
Land l;
if( ! l.Create() )
IncorrectInput();
return 1;
l.PrintMap(); //prints correct output
我想我的程序应该如何工作:
-
调用默认构造函数,不需要自定义构造函数。
检查输入是否满足要求。 如果不是,则返回
false
,从而完成程序。内存还没有被动态分配(停留在nullptr
),没问题。
如果是,创建一个二维数组使用 calloc
(我知道我正在将 C 与 C++ 混合,想使用类,而 vector
不可用)。
用扫描值填充该二维数组。如果扫描的值不是整数,则返回 false,从而完成程序。
打印该数组的值。常量函数。
结束程序,调用析构函数。由于我不知道Create()
是否提前结束(在calloc
之前),我默认将int **map
初始化为nullptr
。如果我分配,map
将不再是nullptr
并且需要被释放。否则,析构函数应该是free
,这就是Clean()
所做的。
Clean()
我遵循动态分配和释放的做法。 calloc
和 free
遵循它们相反的模式。调试确认调用了多少个calloc
s,调用了多少个free
s。
尽管如此,valgrind
仍然报告错误(不是reachable
,实际错误)。具体来说:total heap usage: 184 allocs, 23 frees
。是什么导致了这个错误,我错过了什么?
编辑:初始化 rows
和 columns
成员。将 calloc()
更改为 C++ new
和 delete
。
【问题讨论】:
calloc
和 free
在 C++ 中?
@John3136 见(I know I'm mixing C with C++, wanted to use class and vector is not available).
不会阻止您使用 new
和 delete
即使您“修复”了问题,您的程序也会以各种方式泄漏内存。如果在创建矩阵的过程中,对calloc
的调用之一失败了怎么办?你将如何恢复那段记忆?
另外,像Land l;
这样简单的事情会因为Land
对象中的成员变量未初始化而调用未定义的行为,并且将使用未初始化的rows
和@987654357 调用析构函数@值。
【参考方案1】:
没有内存泄漏。
calloc
不会抛出异常。
顺便说一句,在Land::CreateMap
和许多其他地方检测到空指针尊重。
不要忘记检查calloc
的返回值
更新
例如,
class foo
int* p1;
int* p2;
foo()
p1 = new int;
p2 = new int;
~foo()
delete p1;
delete p2;
;
int main()
foo val;
在foo
的Ctor中,当p2 = new int;
抛出异常时,foo
的Dtor不会被调用,所以,任何人都可以删除p1
!
因此,当您想在 ctor 中使用非 noexcept 运算符 new
分配内存时,您必须使用 RAII 包装器。 C++11 或更高版本有 RAII wapper 类来分配内存,即std::unique_ptr
或std::shared_ptr
。
顺便说一句,
矢量不可用
你使用的是什么环境?
【讨论】:
如果没有内存泄漏,我应该如何解释valgrind
的输出?
等等,等等,等等!你更新的代码使用new
会导致内存泄漏!!
它产生了与 calloc 相同的输出。
我认为你需要扩展你的论点,yumetodo。要么我误解了它,要么你基于一个有缺陷的假设。以上是关于二维数组中的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章
关于Delphi中二维数组的声明和大小调整(对非基本类型数据,小心内存泄漏)
使用 sqlite 的 UIPickerView 中的内存泄漏