A continuación se muestra una forma sencilla de crear matrices 3D utilizando C o C++ en un trozo de memoria para cada matriz. No es necesario usar BOOST (incluso si es agradable), o dividir la asignación entre líneas con indirección múltiple (esto es bastante malo ya que generalmente da una gran penalización de rendimiento al acceder a los datos y fragmenta la memoria).
Lo único que hay que entender es que no existen las matrices multidimensionales, solo las matrices de las matrices (de las matrices). El índice más interno es el más lejano en la memoria.
#include <stdio.h>
#include <stdlib.h>
int main(){
{
// C Style Static 3D Arrays
int a[10][20][30];
a[9][19][29] = 10;
printf("a[9][19][29]=%d\n", a[9][19][29]);
}
{
// C Style dynamic 3D Arrays
int (*a)[20][30];
a = (int (*)[20][30])malloc(10*20*30*sizeof(int));
a[9][19][29] = 10;
printf("a[9][19][29]=%d\n", a[9][19][29]);
free(a);
}
{
// C++ Style dynamic 3D Arrays
int (*a)[20][30];
a = new int[10][20][30];
a[9][19][29] = 10;
printf("a[9][19][29]=%d\n", a[9][19][29]);
delete [] a;
}
}
para su problema real, ya que es potencialmente dos dimensiones desconocidas, hay un problema con mi propuesta en que permite sólo una dimensión desconocida. Hay varias formas de gestionar eso.
La buena noticia es que el uso de variables ahora funciona con C, se llama arrays de longitud variable. Miras here para más detalles.
int x = 100;
int y = 200;
int z = 30;
{
// C Style Static 3D Arrays
int a[x][y][z];
a[99][199][29] = 10;
printf("a[99][199][29]=%d\n", a[99][199][29]);
}
{
// C Style dynamic 3D Arrays
int (*a)[y][z];
a = (int (*)[y][z])malloc(x*y*z*sizeof(int));
a[99][199][29] = 10;
printf("a[99][199][29]=%d\n", a[99][199][29]);
free(a);
}
Si usando C++ la forma más sencilla es probablemente usar la sobrecarga de operadores para seguir con matriz sintaxis:
{
class ThreeDArray {
class InnerTwoDArray {
int * data;
size_t y;
size_t z;
public:
InnerTwoDArray(int * data, size_t y, size_t z)
: data(data), y(y), z(z) {}
public:
int * operator [](size_t y){ return data + y*z; }
};
int * data;
size_t x;
size_t y;
size_t z;
public:
ThreeDArray(size_t x, size_t y, size_t z) : x(x), y(y), z(z) {
data = (int*)malloc(x*y*z*sizeof data);
}
~ThreeDArray(){ free(data); }
InnerTwoDArray operator [](size_t x){
return InnerTwoDArray(data + x*y*z, y, z);
}
};
ThreeDArray a(x, y, z);
a[99][199][29] = 10;
printf("a[99][199][29]=%d\n", a[99][199][29]);
}
El código anterior tiene algún costo indirecto para acceder InnerTwoDArray (pero un buen compilador probablemente puede optimizar de distancia) pero utiliza solo un trozo de memoria para la matriz asignada en el montón. Que suele ser la elección más eficiente.
Obviamente, incluso si el código anterior sigue siendo simple y directo, STL o BOOST lo hace bien, por lo tanto, no es necesario reinventar la rueda. Todavía creo que es interesante saber que se puede hacer fácilmente.
Desenterrando huesos viejos, lo sé ... pero ¿por qué las personas usan C++ cuando cosas "básicas" como matrices multidimensionales vienen gratis con otros lenguajes de nivel superior? ¿Es algo que tienes que usar C++ para que tus manos estén atadas a la espalda? ¿Actuación? – MikeMurko
Hola MikeMurko, en este momento la razón de las manos atadas sería la más correcta. Estaría igualmente feliz de hacer algo como esto en Java o C#. – AndyUK