【发布时间】: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遵循它们相反的模式。调试确认调用了多少个callocs,调用了多少个frees。
尽管如此,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 调用析构函数@值。
标签: c++ arrays memory-management memory-leaks