Как я могу изменить следующий код, чтобы я мог использовать 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);
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;
}
Так я обычно делаю, поэтому я получаю удобочитаемость [] [] с эффективностью хранения в объекте.
Предполагая, что использование стандартной библиотеки 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;
Вы должны решить, хотите ли вы программировать на 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;
}