¿Deberían usarse arreglos en C++?

6 minutos de lectura

avatar de usuario
andreas

Ya que std::list y std::vector existen, ¿hay alguna razón para usar matrices C tradicionales en C++, o deberían evitarse, al igual que malloc?

  • posible duplicado de ¿Cuál es la diferencia entre std::array y std::vector? ¿Cuándo usas uno sobre otro?

    – Alok Guardar

    23 de mayo de 2012 a las 10:31

  • @Als: esa pregunta se refiere a la diferencia entre dos contenedores específicos, mientras que esta pregunta se refiere a la diferencia entre matrices sin formato y contenedores estándar en general.

    – Jon Purdy

    23 mayo 2012 a las 16:58

En C++ 11 donde std::array está disponible, la respuesta es “sí, se deben evitar las matrices”. Antes de C++ 11, es posible que deba usar matrices C para asignar matrices en el almacenamiento automático (es decir, en la pila).

  • sin embargo, muchos compiladores todavía carecen de compatibilidad con C++ 11. Tendrá que decidir cuándo es mejor usar uno en lugar del otro dada la falta de std::array

    – Nowayz

    25 de mayo de 2012 a las 9:59

  • std::array es una plantilla, lo que afecta a los proyectos grandes en términos de tiempo de compilación y, posiblemente, tamaño del código, ya que para cada combinación de T, N, la plantilla se instancia de nuevo.

    – zvrba

    10 de junio de 2012 a las 8:37

  • std::vector garantiza la alineación de datos por estándar, por lo que se puede usar en casi todas partes. Con C++11 realmente no hay razón para usar matrices C.

    – ceros

    10 de junio de 2012 a las 8:54

  • Las matrices de @Nils también garantizan la alineación. Además, la asignación automática de almacenamiento (“la pila”) es mucho más rápida que la asignación dinámica de almacenamiento. Si yo saber tengo exactamente 3 elementos [e.g., coordinates of a triangle]no hay razón para usar vector.

    – zvrba

    10 de junio de 2012 a las 9:15


  • @zvrba: verifique el ensamblaje generado cuando use matrices std::array vs C. No hay diferencia en absoluto.

    – Nemanja Trifunovic

    10 de junio de 2012 a las 13:54

avatar de usuario
james kanze

Definitivamente, aunque con std::array en C++11, prácticamente solo para datos estáticos. Las matrices de estilo C tienen tres ventajas importantes sobre
std::vector:

  • No requieren asignación dinámica. Por esta razón, se prefieren las matrices de estilo C cuando es probable que tenga muchas matrices muy pequeñas. Di algo como un punto de n-dimensión:

    template <typename T, int dims>
    class Point
    {
        T myData[dims];
    // ...
    };
    

    Por lo general, uno podría imaginar que dims será muy pequeño (2 o 3),
    T un tipo incorporado (double), y que podría terminar con
    std::vector<Point> con millones de elementos. Definitivamente no quieres millones de asignaciones dinámicas de 3 dobles.

  • La inicialización estática de soporte. Esto es solo un problema para los datos estáticos, donde algo como:

    struct Data { int i; char const* s; };
    Data const ourData[] =
    {
        { 1, "one" },
        { 2, "two" },
        //  ...
    };
    

    A menudo, esto es preferible a usar un vector (y std::string), ya que evita todos orden de problemas de inicialización; los datos se cargan previamente, antes de que se pueda ejecutar cualquier código real.

  • Finalmente, relacionado con lo anterior, el compilador puede calcular el tamaño real de la matriz a partir de los inicializadores. No tienes que contarlos.

Si tiene acceso a C++ 11, std::array resuelve los dos primeros problemas, y definitivamente debe usarse con preferencia a las matrices de estilo C en el primer caso. Sin embargo, no aborda el tercero, y hacer que el compilador dimensione la matriz de acuerdo con la cantidad de inicializadores sigue siendo una razón válida para preferir las matrices de estilo C.

  • La inicialización de matriz de estilo C también elimina la necesidad de repetirse. int i[] = { 1, 2, 3 }; sigue trabajando con int i[] = { 1, 2, 3, 4 };. array<int, 3> debe cambiarse manualmente a array<int, 4>.

    usuario79758

    23 de mayo de 2012 a las 12:51


  • @JoeWreschnig Un cambio que puedes olvidar fácilmente. Si agrega un elemento, el compilador debería quejarse, pero si elimina uno, terminará con un elemento inicializado 0 adicional al final. Todavía uso matrices de estilo C ampliamente para este tipo de datos estáticos.

    – James Kanze

    23 de mayo de 2012 a las 12:56

  • La primera frase no tiene sentido.

    – Konrad Rodolfo

    23 mayo 2012 a las 14:37

  • El tercer punto se puede resolver con bastante elegancia mediante el uso de un make_array funciónSimilar a make_pair etc. Felicitaciones a @R. Martinho Fernández.

    – Konrad Rodolfo

    23 de mayo de 2012 a las 15:03


  • @KonradRudolph: Claro que sí. Andreas pregunta “¿Deberían usarse arreglos en C++?”, a lo que James responde “Definitivamente, aunque con std::array en C++11, [they should be used] prácticamente solo para datos estáticos”.

    – Jon Purdy

    23 de mayo de 2012 a las 17:02

Nunca digas “nunca”, pero estoy de acuerdo en que su papel se ve muy disminuido por las verdaderas estructuras de datos de STL.

También diría que la encapsulación dentro de los objetos debería minimizar el impacto de elecciones como esta. Si la matriz es un miembro de datos privados, puede intercambiarla sin afectar a los clientes de su clase.

He trabajado en sistemas críticos para la seguridad en los que no se puede utilizar la asignación de memoria dinámica. La memoria tiene que estar siempre en la pila. Por lo tanto, en este caso, usaría matrices ya que el tamaño se fija en el momento de la compilación.

array en c++ le ofrece una alternativa rápida de tamaño fijo de tamaño dinámico std::vector y std::list. estándar::matriz es una de las adiciones en c++11. Proporciona el beneficio de los contenedores estándar al mismo tiempo que proporciona la semántica de tipo agregado de las matrices de estilo C.

así que en c++11 ciertamente usaría std::array, donde se requiera, sobre vector. Pero evitaría la matriz de estilo C en C++03.

avatar de usuario
Luciano Grigore

Por lo general, nono puedo pensar en una razón para usar matrices sin procesar en lugar de, digamos, vectors. Si el código es nuevo.

Es posible que deba recurrir al uso de matrices si sus bibliotecas deben ser compatibles con el código que espera matrices y punteros sin formato.

Sé que mucha gente está señalando std::array para asignar matrices en la pila y std::vector para el montón. Pero ninguno parece admitir la alineación no nativa. Si está haciendo algún tipo de código numérico en el que desea usar instrucciones SSE o VPX (por lo tanto, requiere una alineación de 128 o 256 bytes respectivamente), las matrices C aún parecen ser su mejor opción.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad