2

newanddeleteの代わりにmallocandを使用できるように、次のコードを変更するにはどうすればよい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**に選択肢(など)がないことに注意してください。vectorfloat**

Edit2:この関数は、次のように記述されたプロキシミティクエリパッケージ(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);
4

3 に答える 3

9
  • 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の行列が必要な場合は、1つのブロックに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;
}

これが私が通常行う方法であるため、オブジェクト内ストレージの効率で[][]の読みやすさを得ることができます。

于 2012-10-01T14:46:34.827 に答える
6

標準C++ライブラリの使用がオプションであると仮定すると、次を使用する必要があります。

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

の代わりにfloat**。マイナス面は絶対にありません、そしてあなたは無料で多くの便利なものを手に入れるでしょう。たとえば、側面に数値のペアを渡したり、いくつかの仮定でコーディングしたりしなくても、ベクトルのサイズとその各次元を見つけることができます。ループなしで割り当て、コードなしで削除することができます。

これがオプションでない場合は、次のようにmalloc/freenew[]/に置き換えることができます。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;
于 2012-10-01T14:46:24.953 に答える
3

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;
}
于 2012-10-01T14:59:45.780 に答える