E/S binaria a archivo con matriz dinámica bidimensional

Tengo problemas con la E/S para archivar con una matriz dinámica bidimensional. Compila bien pero no funciona como yo quiero. Ejemplo, guardo el "mapa" de los números 2 y después de esto cambio el número en el código fuente al ejemplo 1 y lo compilo, ahora cargo mi "mapa" de los números 5 pero cuando escribe en ciclo para al final, la salida es 1 no 5. Por favor, ¿alguien puede ayudar a arreglar el código?

#include <iostream>
#include <fstream>
int main()
{
int ** array;

array = new int*[20];
for(int y=0;y<20;y++)
    array[y] = new int[30];

for(int y=0;y < 20;y++)
    for(int x=0;x < 30;x++)
        array[y][x] = 1;

int volba = 1;
std::cin >> volba;

if(volba)
{
    std::ifstream in("map",std::ios::in | std::ios::binary);
    if(!in.is_open())
        std::cout << "in map open error\n";
    in.read((char*)&array, sizeof(array));
    in.close();
    std::cout << "loaded\n";
}
else
{
    std::ofstream out("map",std::ios::out | std::ios::binary);
    if(!out.is_open())
        std::cout << "out map open error\n";
    out.write((char*)&array, sizeof(array));
    out.close();
    std::cout << "saved\n";
}

std::cout << "array\n";
for(int y=0;y < 20;y++)
{
    for(int x=0;x < 30;x++)
        std::cout << array[y][x] << " ";
    std::cout << std::endl;
}

for(int y=0;y<20;y++)
    delete [] array[y];
delete [] array;

return 0;
}

preguntado el 22 de mayo de 12 a las 09:05

2 Respuestas

El principal problema es este: Por la presente

array = new int*[20];

asigna una matriz de punteros, y esto no se convertirá en una matriz bidimensional como lo hará más tarde:

array[y] = new int[30];

Tenga en cuenta que hay una diferencia entre este

// array of pointers to integer arrays
int ** array = new int*[20];
for(int y=0;y<20;y++)
  array[y] = new int[30];

y este

// two dimensional integer array
int array[20][30];

No puede asumir que su matriz de matrices se encontrará en la memoria contigua.


Además: Por la presente

out.write((char*)&array, sizeof(array));

simplemente escribe el puntero, no los datos reales. Trate de imprimir el sizeof(array):

#include <iostream>

int main() {
  int * array = new int[10];
  std::cout << sizeof(array) << std::endl; // probably prints 4 or 8
  return 0;
}

Conclusión: a menos que necesite implementar esto con fines educativos, std :: vector le servirá mucho más convenientemente la gestión de la memoria de forma gratuita. También echa un vistazo a Impulsar la serialización. Proporciona funcionalidad para la serialización de colecciones STL.

contestado el 22 de mayo de 12 a las 10:05

@ user1295618 - He puesto una opción en negrita. Alternativamente, podría usar un bidimensional estático array[20][30]. - moooeeeeep

@ user1295618 - por supuesto que no. La buena manera de programar sería usar std::vector y probablemente Boost Serialization. - moooeeeeep

El error está en el hecho de que sizeof(array) es igual al tamaño de un puntero, no el tamaño de la memoria asignada dinámicamente. Como efecto, solo lee/escribe 4 (u 8) bytes. Use el tamaño real de la matriz (en este caso 20*30) en lugar de sizeof(array).

contestado el 22 de mayo de 12 a las 09:05

Traté de cambiar sizeof(array) a sizeof(int) * 600 pero aún tengo este problema: "Ejemplo, guardo el "mapa" de los números 1 y luego cambio el número en el código fuente al ejemplo 5 y lo compilo, ahora Cargo mi "mapa" de números 1 pero cuando escribe en ciclo al final, la salida es 5, no 1". - controlar

Hay otro problema en su código, vea la respuesta de @moooeeeep. - alex bakulín

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.