我如何为程序修复这个小的内存泄漏
How do I fix this small memory leak for my program?
所以我制作了一个程序,该程序模拟了tic-tac-toe游戏并用valgrind运行它,并说我有内存泄漏。是什么导致了此泄漏,我该如何修复?
这是Valgrind的输出:
==15253==
==15253== HEAP SUMMARY:
==15253== in use at exit: 72,704 bytes in 1 blocks
==15253== total heap usage: 37 allocs, 36 frees, 76,864 bytes allocated
==15253==
==15253== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==15253== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==15253== by 0x4EC5B1F: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.22)
==15253== by 0x40104E9: call_init.part.0 (dl-init.c:72)
==15253== by 0x40105FA: call_init (dl-init.c:30)
==15253== by 0x40105FA: _dl_init (dl-init.c:120)
==15253== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==15253==
==15253== LEAK SUMMARY:
==15253== definitely lost: 0 bytes in 0 blocks
==15253== indirectly lost: 0 bytes in 0 blocks
==15253== possibly lost: 0 bytes in 0 blocks
==15253== still reachable: 72,704 bytes in 1 blocks
==15253== suppressed: 0 bytes in 0 blocks
==15253==
==15253== For counts of detected and suppressed errors, rerun with: -v
==15253== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
这是代码:
main.cpp:
#include <iostream>
#include "../include/Board.h"
using namespace std;
/**
* Main function that is run.
* @return: 0 on exit success
*/
int main() {
Board b;
int r, c;
int moveCount = 0;
cout << "* * * * * Welcome to the Tic-Tac-Toe game! * * * * *" << endl;
cout << "Enter numbers 1, 2, or 3 when prompted for coordinates of your move." << endl;
cout << b.toString() << endl;
// Loops until there are no more possible moves.
while(moveCount < 9) {
// Prompts for coordinates to make a move.
do {
if(moveCount % 2 == 0) {
cout << "Player X's turn, enter the row and column of your move.nRow #:";
}
else {
cout << "Player O's turn, enter the row and column of your move.nRow #:";
}
cin >> r;
cout << "Column #:";
cin >> c;
// Checks if the move is valid.
if(b.canPut((r - 1), (c - 1)) != 1) {
cout << "nInvalid move, re-enter the desired coordinates.n" << endl;
}
}while(b.canPut((r - 1), (c - 1)) != 1);
// Makes the move.
if(moveCount % 2 == 0) {
b.makeMove((r - 1), (c - 1), X);
}
else {
b.makeMove((r - 1), (c - 1), O);
}
cout << b.toString() << endl;
// Checks if there is a winner and breaks the loop if there is.
if(b.checkWinner() != 0)
break;
moveCount++;
}
// Prints the appropriate statement base on the winning status, if any.
if(moveCount == 9) {
cout << "nGame over, stalemate." << endl;
}
else {
if(b.checkWinner() == X) {
cout << "nPlayer X has won!!!" << endl;
}
else if(b.checkWinner() == O) {
cout << "nPlayer O has won!!!" << endl;
}
}
return 0;
}
board.h:
#ifndef BOARD_H
#define BOARD_H
#include <string>
#define X 1
#define O 5
#define SIZE 3
/**
* Board class for tic-tac-toe project.
*/
class Board {
private:
int **grid;
public:
Board();
~Board();
int checkWinner();
int canPut(int r, int c);
void makeMove(int r, int c, int val);
std::string toString();
};
#endif
board.cpp:
#include "../include/Board.h"
#include <string>
using namespace std;
/**
* Constructor for a Board object.
*/
Board::Board() {
grid = new int*[SIZE];
// Creates all the 1D arrays to make the 2D array.
for(int ctr = 0; ctr < SIZE; ctr++) {
grid[ctr] = new int[SIZE];
for(int i = 0; i < SIZE; i++) {
grid[ctr][i] = 0;
}
}
}
/**
* Destructor for a Board object.
*/
Board::~Board() {
for(int ctr = 0; ctr < SIZE; ctr++) {
delete[] grid[ctr];
}
delete[] grid;
}
/**
* Checks if there is a winner for the current game.
* @return: 0 if no winner, X if X player wins or O if O player wins
*/
int Board::checkWinner() {
int sum;
// Checks all the rows for a winner.
for(int i = 0; i < SIZE; i++) {
sum = 0;
for(int ctr = 0; ctr < SIZE; ctr++) {
sum += grid[i][ctr];
}
if(sum == 3) {
return X;
}
else if(sum == 15) {
return O;
}
}
// Checks all the columns for a winner.
for(int a = 0; a < SIZE; a++) {
sum = 0;
for(int b = 0; b < SIZE; b++) {
sum += grid[b][a];
}
if(sum == 3) {
return X;
}
else if(sum == 15) {
return O;
}
}
// Checks the top-left to bottom-right diagonal for a winner.
sum = 0;
for(int i = 0; i < SIZE; i++) {
sum += grid[i][i];
}
if(sum == 3) {
return X;
}
else if(sum == 15) {
return O;
}
// Checks the top-right to bottom-left diagonal for a winner.
sum = 0;
for(int r = 0, c = SIZE - 1; r < SIZE && c > 0; r++, c--) {
sum += grid[r][c];
}
if(sum == 3) {
return X;
}
else if(sum == 15) {
return O;
}
// Returns zero because after checking all the possibilities, a winner has not been found.
return 0;
}
/**
* Determines if there is an open spot on the board at the given coordinates.
* @param r: the row to be checked
* @param c: the column to be checked
* @return: 1 if there is an open spot, 0 if not
*/
int Board::canPut(int r, int c) {
if(grid[r][c] == 0)
return 1;
return 0;
}
/**
* Simulates making a move for a player.
* @param r: the row to set the value
* @param c: the column to set the value
* @param val: the value to be set at the given coordinates
*/
void Board::makeMove(int r, int c, int val) {
grid[r][c] = val;
}
/**
* Creates a representation of the board as a string.
* @return: string of the board
*/
string Board::toString() {
char a, b, c;
string output = "Board:n";
// Loops through every line for the 2D array.
for(int ctr = 0; ctr < SIZE; ctr++) {
// Loops through every value of the 1D array being checked.
for(int i = 0; i < SIZE; i++) {
output += ' ';
if(grid[ctr][i] == X) {
output += 'X';
}
else if(grid[ctr][i] == O) {
output += 'O';
}
else {
output += ' ';
}
if(i != (SIZE - 1)) {
output.append(" |");
}
else {
output += 'n';
}
}
// Pads each line with a line of '-' characters.
if(ctr != (SIZE - 1)) {
for(int i = 0; i < (SIZE * 4) - 1; i++) {
output += '-';
}
output += 'n';
}
}
return output;
}
因此,内存泄漏不是您的问题。在执行任何代码之前,这是程序进行初始化时发生的内存泄漏。
valgrind通常会忽略这些。它具有一个文件,该文件具有在各个平台上的各个库中需要忽略的内容列表。也许您使用了一个valgrind选项,该选项告诉它不要忽略它们,或者也许在该平台上的LibstDC 的确切版本都没有正确设置。
作为无关的C 样式说明,我会说我真的不喜欢您在 board.h 中使用#define
。您应该声明 const
。
您的代码看起来不错,但我建议不要将指针用于网格的指针,这有点棘手。而不是int **grid
,有int grid[SIZE][SIZE]
。那么,您不需要任何新的和删除的呼叫 - 不需要内存泄漏的来源!除非大小很大,否则您可以在堆栈上分配板。如果大小很大,则只需在b = new Board()
上分配堆的板即可。(别忘了删除它!)
相关文章:
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 尽管遵循了规则,内存泄漏在哪里
- 为什么调用堆栈数组会导致内存泄漏
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 使用模板类的自定义列表类型中的内存泄漏
- 为什么以下C++代码中存在内存泄漏?
- OpenCV 我应该使用智能指针来防止内存泄漏吗?
- 我是否生成线程并导致内存泄漏?
- 多线程程序中出现意外的内存泄漏
- 为什么此函数会导致内存泄漏?
- 在 C++ 库中使用cythonized python时内存泄漏
- 需要帮助查找内存泄漏
- 瓦尔格林德的内存泄漏使用新的
- 无法找出我的代码中的内存泄漏
- C++ 结构内部的unordered_map会导致内存泄漏问题吗?
- 可视化 使用 VS Code 查找C++应用程序中的内存泄漏
- Shared_ptr双链接列表内存泄漏
- C++ 在类中使用常量引用文本时 O2 内存泄漏