如何更改以下代码,以便我可以使用 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;
}
编辑1:请注意,我必须使用一个以float**
为参数的函数(不是我写的),除了使用float**
之外,我别无选择(例如vector
)。
编辑2:该函数来自邻近查询包(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;
}
请注意,这实际上不是很理想。如果你想要 3x3 矩阵,你最好在一个块中分配 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;
}