Инициализация / преобразование 3d-массива c / c ++ - PullRequest
0 голосов
/ 03 апреля 2011
float sampleGrid1[5][5][5] =
{
    {
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0}

    },

    {
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 1.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0}

    },

    {
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 1.0, 0.0, 0.0},
        {0.0, 1.0, 1.0, 1.0, 0.0},
        {0.0, 0.0, 1.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0}

    },

    {
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 1.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0}

    },

    {
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0},
        {0.0, 0.0, 0.0, 0.0, 0.0}

    }
};

typedef struct
{
  int Nx;
  int Ny;
  int Nz;
  float*** M;
}OG;

Соответствующая функция:

OG *newOG(){
    OG *newOG = (OG *)malloc(sizeof(OG));
    if (newOG == NULL)
    {
        throw std::exception("newOG : no memory is available");
    }

    return newOG;
}

int initiateOG(OG *MyOG)
{

    ifstream dump("OGdump3.txt");

    if (dump.is_open())
    {   
        while ( dump.good() )
        {   
            dump >> MyOG->Nx;
            dump >> MyOG->Ny;
            dump >> MyOG->Nz;

            MyOG->M = new float**[MyOG->Nx];
            for(int i = 0; i < MyOG->Nx; i++)
            {
                MyOG->M[i] = new float*[MyOG->Ny];

                for(int j = 0; j < MyOG->Ny; j++)
                {
                    MyOG->M[i][j] = new float[MyOG->Nz];
                }
            }
            for(int z=0;z < MyOG->Nz; z++){

                for(int y=0;y < MyOG->Ny; y++){

                    for(int x=0;x < MyOG->Nx; x++){

                        dump >> MyOG->M[x][y][z];
                    }

                }

            }


        }

    dump.close();
    }
    else return 0; 
    return 1;
}

Я хочу жестко закодировать некоторые примеры сеток в код, но не знаю, как лучше их создать, нужно ли использовать циклы?

я не хочу менять свою структуру typedef OG, если это возможно

Изменено:

OG *occupancyGrid;

 void initialize3dArray(int x, int y, int z,float*** array)
    {
        array = new float**[x];
        for(int i = 0; i < x; i++)
        {
            array[i] = new float*[y];

            for(int j = 0; j < y; j++)
            {
                array[i][j] = new float[z];
            }
        }

    }

   void sampleOG1()
    {
        occupancyGrid = newOG();
        occupancyGrid->Nx = 5;
        occupancyGrid->Ny = 5;
        occupancyGrid->Nz = 5;

        initialize3dArray(5, 5, 5,occupancyGrid->M);

        for(int z=0;z < occupancyGrid->Nz; z++){

            for(int y=0;y < occupancyGrid->Ny; y++){

                for(int x=0;x < occupancyGrid->Nx; x++){

                    occupancyGrid->M[x][y][z] = sampleGrid1[x][y][z];
                }

            }

        }

    }

initialize3dArray У этой функции нет ошибки компиляции ,, но она по-прежнему вызываетпрограмма для сбоя

Ответы [ 3 ]

3 голосов
/ 03 апреля 2011

Да. это не скомпилируется, потому что float[5][5][5] и float *** не одного типа. Они даже не совместимого типа. Нельзя автоматически конвертировать в другого.

Однако, float[5][5][5] может конвертироваться в float (*)[5][5] автоматически. Так что это юридический код:

    float (*m)[5][5];
    m = sampleGrid1;  //legal - allowed!

Демо: http://ideone.com/RwAwI

Так определите OG как,

struct OG
{
  int Nx;
  int Ny;
  int Nz;
  float (*M)[5][5];
};

Если вы OG как определено выше, то вы можете написать это:

OG* temp = newOG();
temp->Nx = 5;
temp->Ny = 5;
temp->Nz = 5;
occupancyGrid->M = sampleGrid1; //DONT use &
1 голос
/ 03 апреля 2011

Ошибка не ясна? float[5][5][5] не так относится к float***, как вы думаете.

Используйте взамен std::vector<std::vector<std::vector<float> > > и избегайте всего беспорядка.

1 голос
/ 03 апреля 2011

float x[2][2] - это двумерный массив с плавающей точкой - это не одномерный массив указателей для плавающего числа. Преобразование из массива в указатель работает только для первого измерения таких массивов.

Учитывая float x[2][2], вы резервируете место для 4 поплавков. Переменная float ** с другой стороны - это указатель на указатель на число с плавающей точкой - в float x[2][2]

нет указателей.

То же самое относится и к 3D-массиву - ваш 3D-массив не имеет скрытно скрытых указателей внутри, его нельзя рассматривать как float ***

...