How to replace 'malloc' and 'free' with 'new' and 'delete'?

北战南征 提交于 2019-12-08 01:17:25
  • T* a = (T*)malloc(sizeof(T)) becomes new T.
  • T* b = (T*)malloc(N * sizeof(T)) becomes new T[N].
  • free(a) becomes delete a.
  • free(b) becomes delete[] b.

So you get:

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;
}

Note that this is actually not very optimal. If you want 3x3 matrices, you're better off allocating 9 floats in one block.

Also note that your C is incorrect.

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

should be

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

Your code probably "works" because you're compiling for 32-bit, where float and float* are 4 bytes. On a 64 bit build, float* is 8 bytes.


Honestly, though, since your dimensions are fixed and small, you should store everything in the object itself:

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;
}

This is how I usually do it, so I get the readability of [][] with the efficiency of in-object storage.

Assuming that using the standard C++ library is an option, you should use

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

instead of float**. There is absolutely no downside, and you would get many convenient things for free. For example, you would be able to find the size of the vector and each of its dimensions without passing a pair of numbers on the side, or coding in some assumptions. You would be able to allocate without loops, and delete with no code at all.

If this is not an option, you can replace malloc/free with new[]/delete[] as follows:

// 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;

You should decide if you want to program in C (hence, no classs) or C++ (hence, no plain C, when C++ library exist).

Right now you just have C + some classes.

Respect to what you did (a class who wraps a bidimensional fixed array) a more proper way can be this:

#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;
}

Note that there is no need to use dynamic memory.

If you want to use dynamic memory(may be because the array size should be bigger) you can rely on std::vector as a container:

#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;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!