Use shared_ptr to avoid memory leaks

This commit is contained in:
Martin Asprusten
2026-08-29 09:31:26 +02:00
parent 99a496c0ab
commit eac2a41f18
+16 -27
View File
@@ -1,4 +1,5 @@
#include <cstdint> #include <cstdint>
#include <memory>
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
#include <emscripten/bind.h> #include <emscripten/bind.h>
#include <emscripten/val.h> #include <emscripten/val.h>
@@ -16,8 +17,8 @@ struct City {
}; };
struct State{ struct State{
float* weights; std::shared_ptr<float[]> weights;
uint8_t* adjacencyMatrix; std::shared_ptr<uint8_t[]> adjacencyMatrix;
float lowerBound; float lowerBound;
bool finished = false; bool finished = false;
std::vector<std::pair<int, int>> paths; std::vector<std::pair<int, int>> paths;
@@ -30,7 +31,7 @@ struct SplitState {
}; };
double reduceWeights(float* weights, int numberOfCities) { double reduceWeights(std::shared_ptr<float[]> weights, int numberOfCities) {
double totalReduced = 0; double totalReduced = 0;
for (int row = 0; row < numberOfCities; row++) { for (int row = 0; row < numberOfCities; row++) {
@@ -74,7 +75,7 @@ double reduceWeights(float* weights, int numberOfCities) {
return totalReduced; return totalReduced;
} }
std::pair<int, int> findPivotPoint(float* weights, int numberOfCities) { std::pair<int, int> findPivotPoint(std::shared_ptr<float[]> weights, int numberOfCities) {
int bestRow = -1; int bestRow = -1;
int bestColumn = -1; int bestColumn = -1;
double bestIncrease = -1; double bestIncrease = -1;
@@ -121,7 +122,7 @@ std::pair<int, int> findPivotPoint(float* weights, int numberOfCities) {
return std::pair<int, int>(bestRow, bestColumn); return std::pair<int, int>(bestRow, bestColumn);
} }
int getDegreeOfNode(int nodeNumber, uint8_t* adjacencyMatrix, int numberOfCities) { int getDegreeOfNode(int nodeNumber, std::shared_ptr<uint8_t[]> adjacencyMatrix, int numberOfCities) {
int degree = 0; int degree = 0;
for (int column = 0; column < numberOfCities; column++) { for (int column = 0; column < numberOfCities; column++) {
degree += adjacencyMatrix[nodeNumber * numberOfCities + column]; degree += adjacencyMatrix[nodeNumber * numberOfCities + column];
@@ -130,26 +131,23 @@ int getDegreeOfNode(int nodeNumber, uint8_t* adjacencyMatrix, int numberOfCities
} }
void multiplyAdjacencyMatrices(int** matrix, int** multiplier, int size) { void multiplyAdjacencyMatrices(int** matrix, int** multiplier, int size) {
int** temporary = new int*[size]; std::shared_ptr<int[]> temporary(new int[size * size]);
for (int row = 0; row < size; row++) { for (int row = 0; row < size; row++) {
temporary[row] = new int[size];
for (int column = 0; column < size; column++) { for (int column = 0; column < size; column++) {
int result = 0; int result = 0;
for (int k = 0; k < size; k++) { for (int k = 0; k < size; k++) {
result += matrix[row][k] * multiplier[k][column]; result += matrix[row][k] * multiplier[k][column];
} }
temporary[row][column] = result; temporary[row * size + column] = result;
} }
} }
// Copy into original matrix // Copy into original matrix
for (int row = 0; row < size; row++) { for (int row = 0; row < size; row++) {
for (int column = 0; column < size; column++) { for (int column = 0; column < size; column++) {
matrix[row][column] = temporary[row][column]; matrix[row][column] = temporary[row * size + column];
} }
delete [] temporary[row];
} }
delete [] temporary;
} }
void disallowSubloops(State &state, int pivotRow, int pivotColumn, int numberOfCities) { void disallowSubloops(State &state, int pivotRow, int pivotColumn, int numberOfCities) {
@@ -218,8 +216,8 @@ void disallowSubloops(State &state, int pivotRow, int pivotColumn, int numberOfC
} }
State createNewStateOnPivot(int pivotRow, int pivotColumn, State originalState, int numberOfCities) { State createNewStateOnPivot(int pivotRow, int pivotColumn, State originalState, int numberOfCities) {
uint8_t* adjacencyMatrixCopy = new uint8_t[numberOfCities * numberOfCities]; std::shared_ptr<uint8_t[]> adjacencyMatrixCopy(new uint8_t[numberOfCities * numberOfCities]);
float* weightsCopy = new float[numberOfCities * numberOfCities]; std::shared_ptr<float[]> weightsCopy(new float[numberOfCities * numberOfCities]);
for (int row = 0; row < numberOfCities; row++) { for (int row = 0; row < numberOfCities; row++) {
for (int column = 0; column < numberOfCities; column++) { for (int column = 0; column < numberOfCities; column++) {
@@ -263,9 +261,6 @@ SplitState splitState(State state, int numberOfCities) {
std::pair<int, int> pivotPoint = findPivotPoint(state.weights, numberOfCities); std::pair<int, int> pivotPoint = findPivotPoint(state.weights, numberOfCities);
if (pivotPoint.first == -1 || pivotPoint.second == -1) { if (pivotPoint.first == -1 || pivotPoint.second == -1) {
splitState.wasSplittable = false; splitState.wasSplittable = false;
delete [] state.adjacencyMatrix;
delete [] state.weights;
return splitState; return splitState;
} }
@@ -279,7 +274,7 @@ SplitState splitState(State state, int numberOfCities) {
return splitState; return splitState;
} }
double getActualWeight(uint8_t* adjacencyMatrix, double* weights, int numberOfCities) { double getActualWeight(std::shared_ptr<uint8_t[]> adjacencyMatrix, std::shared_ptr<double[]> weights, int numberOfCities) {
double totalWeight = 0; double totalWeight = 0;
for (int row = 0; row < numberOfCities; row++) { for (int row = 0; row < numberOfCities; row++) {
for (int column = 0; column < numberOfCities; column++) { for (int column = 0; column < numberOfCities; column++) {
@@ -301,7 +296,7 @@ std::vector<int> findShortestPath(std::vector<std::vector<double>> jsWeights) {
int numberOfCities = jsWeights.size(); int numberOfCities = jsWeights.size();
double* weights = new double[numberOfCities * numberOfCities]; std::shared_ptr<double[]> weights(new double[numberOfCities * numberOfCities]);
for (int row = 0; row < numberOfCities; row++) { for (int row = 0; row < numberOfCities; row++) {
for (int column = 0; column < numberOfCities; column++) { for (int column = 0; column < numberOfCities; column++) {
weights[row * numberOfCities + column] = jsWeights.at(row).at(column); weights[row * numberOfCities + column] = jsWeights.at(row).at(column);
@@ -314,8 +309,8 @@ std::vector<int> findShortestPath(std::vector<std::vector<double>> jsWeights) {
// Create a state // Create a state
State initialState; State initialState;
initialState.weights = new float[numberOfCities * numberOfCities]; initialState.weights = std::shared_ptr<float[]>(new float[numberOfCities * numberOfCities]);
initialState.adjacencyMatrix = new uint8_t[numberOfCities * numberOfCities]; initialState.adjacencyMatrix = std::shared_ptr<uint8_t[]>(new uint8_t[numberOfCities * numberOfCities]);
for (int row = 0; row < numberOfCities; row++) { for (int row = 0; row < numberOfCities; row++) {
for (int column = 0; column < numberOfCities; column++) { for (int column = 0; column < numberOfCities; column++) {
initialState.adjacencyMatrix[row * numberOfCities + column] = 0; initialState.adjacencyMatrix[row * numberOfCities + column] = 0;
@@ -328,7 +323,7 @@ std::vector<int> findShortestPath(std::vector<std::vector<double>> jsWeights) {
queue.push(initialState); queue.push(initialState);
double currentBest = 1e100; double currentBest = 1e100;
uint8_t* bestAdjacenyMatrix = NULL; std::shared_ptr<uint8_t[]> bestAdjacenyMatrix = NULL;
while (!queue.empty()) { while (!queue.empty()) {
State nextState = queue.top(); State nextState = queue.top();
@@ -343,10 +338,7 @@ std::vector<int> findShortestPath(std::vector<std::vector<double>> jsWeights) {
if (actualWeight < currentBest) { if (actualWeight < currentBest) {
currentBest = actualWeight; currentBest = actualWeight;
bestAdjacenyMatrix = nextState.adjacencyMatrix; bestAdjacenyMatrix = nextState.adjacencyMatrix;
} else {
delete [] nextState.adjacencyMatrix;
} }
delete [] nextState.weights;
continue; continue;
} }
@@ -363,9 +355,6 @@ std::vector<int> findShortestPath(std::vector<std::vector<double>> jsWeights) {
while (!queue.empty()) { while (!queue.empty()) {
State stateToDelete = queue.top(); State stateToDelete = queue.top();
queue.pop(); queue.pop();
delete [] stateToDelete.adjacencyMatrix;
delete [] stateToDelete.weights;
} }
std::vector<int> path; std::vector<int> path;