Как заменить ‘malloc’ и ‘free’ на ‘new’ и ‘delete’?

Как я могу изменить следующий код, чтобы я мог использовать new а также delete вместо malloc а также free?

#include <iostream>
#include <cstdlib>
#include <cstdio>
using namespace std;

class myclass{
private:
float **m_R;
public:
myclass();
~myclass();
float **getR(void);
void setR(void);
};

myclass::myclass()
{
// first allocate rows (for pointers)
m_R = (float**)malloc(3*sizeof(float));
// next allocate columns for float values
for(int i=0;i<3;i++)
*(m_R+i) = (float*)malloc(3*sizeof(float));
}

myclass::~myclass()
{
// first free memory allocated by columns
for(int i = 0; i < 3; i++)
{
free(m_R[i]);
}
// next free memory allocated by rows
free(m_R);
}

void myclass::setR(void)
{
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
m_R[i][j] = 10*i+j;
//cout << m_R[i][j] << ", ";
}
//cout << "\n";
}
}

float **myclass::getR(void)
{
return m_R;
}

int main () {

myclass obj;
obj.setR();

for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
printf("%02d, ",(int)obj.getR()[i][j]);
}
cout << "\n";
}

return 0;
}

Edit1: обратите внимание, что я должен использовать функцию (не написана мной), которая принимает float** в качестве аргумента, и у меня нет выбора (например, vector) чем с помощью float**,

Edit2: функция из Proximity Query Package (PQP) написана следующим образом:

int
PQP_Distance(PQP_DistanceResult *result,
PQP_REAL R1[3][3], PQP_REAL T1[3], PQP_Model *o1,
PQP_REAL R2[3][3], PQP_REAL T2[3], PQP_Model *o2,
PQP_REAL rel_err, PQP_REAL abs_err,
int qsize = 2);

1

Решение

  • T* a = (T*)malloc(sizeof(T)) становится new T,
  • T* b = (T*)malloc(N * sizeof(T)) становится new T[N],
  • free(a) становится delete a,
  • free(b) становится delete[] b,

Итак, вы получите:

myclass::myclass()
{
// first allocate rows (for pointers)
m_R = new float*[3];
// next allocate columns for float values
for(int i=0;i<3;i++)
*(m_R+i) = new float[3];
}

myclass::~myclass()
{
// first free memory allocated by columns
for(int i = 0; i < 3; i++)
{
delete[] m_R[i];
}
// next free memory allocated by rows
delete [] m_R;
}

Обратите внимание, что это на самом деле не очень оптимально. Если вы хотите матрицы 3х3, лучше выделить 9 поплавков в одном блоке.

Также обратите внимание, что ваш C неверен.

m_R = (float**)malloc(3*sizeof(float));

должно быть

m_R = (float**)malloc(3*sizeof(float*));

Ваш код, вероятно, «работает», потому что вы компилируете для 32-битной, где float а также float* 4 байта. На 64-битной сборке, float* 8 байт.


Честно говоря, так как ваши размеры фиксированы и малы, вы должны хранить все в самом объекте:

class myclass{
private:
float m_R[3][3];
public:
myclass() {}
~myclass() {}
void setR(void);
float* operator[](unsigned i) { return m_R[i]; }
const float* operator[](unsigned i) const { return m_R[i]; }
};

void myclass::setR(void)
{
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
(*this)[i][j] = 10*i+j;
//cout << (*this)[i][j] << ", ";
}
//cout << "\n";
}
}

int main () {

myclass obj;
obj.setR();

for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
printf("%02d, ",(int)(obj[i][j]));
}
cout << "\n";
}

return 0;
}

Так я обычно делаю, поэтому я получаю удобочитаемость [] [] с эффективностью хранения в объекте.

8

Другие решения

Предполагая, что использование стандартной библиотеки C ++ является опцией, вы должны использовать

std::vector<std::vector<float> > m_R;

вместо float**, Там нет абсолютно никаких недостатков, и вы получите много удобных вещей бесплатно. Например, вы сможете найти размер вектора и каждое из его измерений, не пропуская пару чисел сбоку или не кодируя некоторые предположения. Вы сможете размещать без циклов и удалять без кода вообще.

Если это не вариант, вы можете заменить malloc/free с new[]/delete[] следующее:

// Creating
float **m_R = new float*[10];
for (int i = 0 ; i != 10 ; i++) {
m_R[i] = new float[20];
}

// Deleting
for (int i = 0 ; i != 10 ; i++) {
delete[] m_R[i];
}
delete[] m_R;
5

Вы должны решить, хотите ли вы программировать на C (следовательно, нет класса) или C ++ (следовательно, нет простого C, когда существует библиотека C ++).

Прямо сейчас у вас есть C + некоторые классы.

Уважение к тому, что вы сделали (класс, который оборачивает двумерный фиксированный массив)
более правильный путь может быть таким:

#include <iostream>
#include <iomanip>
#include <cassert>

class myclass
{
public:
mycalss() :m() {}

float& at(size_t r, size_t c)
{ return m[r][c]; }

const float& at(size_t r, size_t c) const
{ return m[r][c]; }

void setR()
{
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
m[i][j] = 10*i+j;
}

private:
float m[3][3];
};

int main ()
{
using namespace std;

myclass obj;
obj.setR();

for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
cout << setw(2) << obj.at(i,j) << endl;
return 0;
}

Обратите внимание, что нет необходимости использовать динамическую память.

Если вы хотите использовать динамическую память (возможно, размер массива должен быть больше)
Вы можете положиться на std :: vector в качестве контейнера:

#include <iostream>
#include <iomanip>
#include <vector>
#include <cassert>

class myclass
{
public:
mycalss(unsigned rows_, unsigned cols_) :m(), rows(rows_), cols(cols_)
{ m.resize(rows_*cols_); }

float& at(size_t r, size_t c)
{ return m[r*cols+c]; }

const float& at(size_t r, size_t c) const
{ return m[r*cols+c]; }

void setR()
{
for(int i=0;i<rows;i++)
for(int j=0;j<cols;j++)
at(i,j) = 10*i+j;
}

private:
std::vector<float> m;
size_t rows, cols;
};

int main ()
{
using namespace std;

static const size_t R=4, C=4;
myclass obj(R,C);
obj.setR();

for(int r=0;r<R;r++)
for(int c=0;c<C;c++)
cout << setw(2) << obj.at(r,c) << endl;
return 0;
}
3
По вопросам рекламы [email protected]