2012-08-22 14 views
5

Esto es parte de una asignación sin embargo yo sólo pidiendo una aclaración:C++ sin STL

cargar datos de ATM.txt y almacenarlos en una matriz dinámica (tipo ATM, no STL) cuando el programa se inicia.

¿Cómo hago exactamente las matrices dinámicas sin STL? Pensé que tal vez la tarea significa usar punteros, el "Tipo de ATM" me tiró.

Se menciona otra vez:

archivo accounts.txt en una matriz dinámica (Tipo de cuenta, no STL)

parte --no de Asignación

nunca he entendido el uso de operaciones inseguras de memoria, por ejemplo, tirando del número de elementos en un archivo de la primera línea:

por ej.

5 
abc 
def 
hij 
kml 
mno 

¿No sería más inteligente para utilizar STL (vectores, o C++ 11 arrays) y no depender de la cantidad en el archivo, ya que puede no ser exacta que causan desbordamientos de búfer, etc?

// Editar definir una cuenta de clases en un archivo que contiene Account.h los miembros de datos: cliente identificación, número de BSB, etc.

Asumo cuenta y tipos de cajeros automáticos son aquellas clases.

+3

"¿No sería más inteligente para utilizar STL" por supuesto que lo haría. :) Pero si se trata de una tarea, esto tiene un valor educativo. –

+0

¿Qué es un "tipo de ATM"? –

+1

ATM no es un término estándar o conocido en C++. ¿Su tarea/curso lo define? –

Respuesta

4

La forma más básica de matriz dinámica es otro creado con new[], y destruyeron usando delete[]:

ATM * atms = new ATM[count]; 
// do stuff with the array 
delete [] atms; 

Sin embargo, esto trae el peligro de que el código utilizando la matriz podría lanzar una excepción, retorno de la función , o de lo contrario, evitar que ocurra el delete[]. Si eso sucede, perderá el único puntero a la memoria asignada, y seguirá siendo asignado pero inaccesible; esto se conoce como pérdida de memoria. Por esta razón, es mejor para envolver la matriz en una clase, con:

variables miembro
  • para almacenar un puntero a la matriz, y (opcionalmente) su tamaño
  • constructores y/o funciones para asignar la matriz
  • un destructor para eliminar la matriz
  • función (opcionalmente) (s) para cambiar el tamaño de la matriz

Eliminación de la asignación en destructor de un objeto utiliza el principio de RAII para asegurar que t La matriz se elimina una vez que ya no es necesaria.

Esto deja un peligro más: si copia este objeto de matriz, terminará con dos objetos que intentan eliminar la misma matriz, lo cual es desastroso. Para evitar esto, deberá considerar el Rule of Three. Escriba un constructor de copia y un operador de asignación de copia para asignar una nueva matriz y copiar el contenido; o eliminarlos. (Si está aprendiendo C++ anticuado, entonces no puede eliminar las funciones de los miembros, por lo que tendrá que declararlas como privadas y no implementarlas en su lugar).

¿No sería más inteligente usar STL?

Normalmente, sí. Pero si está aprendiendo C++, es una buena idea comprender cómo funciona la administración de memoria, así como también cómo lograr que la biblioteca lo maneje por usted. Eso es probablemente parte del objetivo de este ejercicio.

+0

Esta es una publicación muy informativa, gracias por explicar los peligros. Usualmente uso un constructor para desasignar – user1617478

1

Un enfoque común para este tipo de asignación sería simular el comportamiento de autoexpansión de un vector por su cuenta. Asigne una matriz para sus datos en el montón, y realice un seguimiento de su longitud y la cantidad de elementos que ha almacenado en la matriz.

Una vez que haya llenado la matriz con sus datos, amplíe el tamaño máximo en cierta cantidad y asigne una nueva matriz. Esto le permite copiar los datos de la matriz anterior en la nueva matriz, y luego continuar agregando elementos hasta que se quede sin espacio de nuevo.

+5

En realidad, el enfoque * común sería decidir que nunca se pueden tener más de 1024 entradas, usar una matriz fija y esperar lo mejor ;-) –

+0

¿Alguien realmente hace esto en producción? ¿O es más una forma de aprender cómo funciona? – user1617478

+0

@ user1617478: Mucha gente * do *; pero en mi opinión ninguno de ellos * debería *. Pero ciertamente es útil aprender cómo funciona la administración de memoria y por qué debe evitar hacerlo usted mismo cuando sea posible. –

0

Básicamente, si necesita implementar una matriz dinámica sin utilizar STL, debe ocuparse explícitamente de la asignación/desasignación de memoria.

Básicamente, usted tiene que:

  • asignar espacio con malloc se construye o se utiliza
  • Realizar un seguimiento de los elementos eliminados insertados/la primera matriz de tiempo
  • Uso realloc cuando haya terminado el espacio asignado
  • Libere el espacio asignado cuando se destruye la matriz

Por supuesto la implementación un buen contenedor STL como std :: vector no es una tarea fácil (¡con el tiempo una buena tarea!).

Lo que puedo sugerir es la siguiente:

  • evitar en la medida de lo posible reasignación. Cuando el espacio esté terminado, asigne un poco más de espacio para evitar llamar continuamente a realloc (vea std :: vector :: reserva)
  • Evite reasignar espacio cuando se eliminan elementos. Una vez que haya asignado, a menos que el uso de memoria sea demasiado alto, deje el espacio asignado como está, para evitar una reasignación futura.
+0

Siempre he pensado que la memoria administrada por vector es mucho más eficiente que una básica cuando está completa y hace una matriz más grande y la copia. – user1617478

+0

@ user1617478: Dado que la memoria del vector tiene que ser un único bloque contiguo, esa es la única forma de administrarlo. Lo hace lo más eficiente posible al crecer exponencialmente (lo que reduce el número de reasignaciones a medida que crece) y le permite reservar espacio para evitar reasignaciones. –

0

¿No sería más inteligente para utilizar STL (vectores, o C++ 11 arrays) y no depender del número en el archivo, ya que puede no ser exacta causando desbordamientos de búfer, etc?

Las partes internas de std :: vector no son mágicas. Es posible hacer manualmente lo que std :: vector hace por usted.

Parece que eso es lo que se supone que debes hacer para esta tarea; Cree su propio "tipo de cajero automático" que pueda administrar datos de lectura de forma segura desde el archivo ATM.txt, y un "Tipo de cuenta" que pueda contener datos del archivo accounts.txt. Probablemente debería obtener una aclaración de quien escribió la tarea sobre cómo exactamente esperan que se diseñen/usen estos tipos. También mirando hacia atrás a los materiales de la clase que tiene debe decirle lo que necesita saber en términos de uso de matrices dinámicas.

-1

ya que esta es la tarea que no queremos dar respuestas directamente, pero en general lo que propongo es:

  1. hacer una clase myDynamicArray
  2. hacer que la clase contener un int o largo para almacenar gama tamaño
  3. Asigne memoria para su matriz usando "nuevo". A partir de la asignación, parece que podría ser una matriz de cadenas o, si el profesor prohibe estrictamente STL (la cadena ahora se considera STL), será una matriz de matrices de caracteres.
  4. Escriba un método de inserción que, antes de insertar, verifique el tamaño (vea el n. ° 2) de su matriz y, si no es lo suficientemente grande, lo hace más grande. Una forma de hacerlo sin usar las funciones pre-C++, que supongo que es mejor ya que es una clase C++, es asignar una nueva matriz de mayor tamaño -> copiar datos de la matriz anterior -> Insertar cualquier dato nuevo. ¿Cuánto más grande? Puede elegir, digamos, un 20% más grande con cada nueva asignación. C# de Microsoft asigna "el próximo número primo más grande" de elementos, aunque tienen rutinas de asignación de memoria realmente rápidas.
  5. No olvide borrar() la matriz dinámica cuando termine con ella (lo que significa "terminado" depende de la asignación). Tenga en cuenta que una vez que el programa sale, técnicamente la memoria debe liberarse automáticamente, pero es una mala práctica no liberarse usted mismo (piense en programas no académicos más grandes que no se cierran regularmente).

Evitaría el código de plantilla proporcionado por otro usuario. Estoy seguro de que es un gran código, pero va a levantar una ceja para utilizar algo que avanzó en una clase temprana de C++.

Lectura recomendada: http://www.cplusplus.com/doc/tutorial/dynamic/