Diapositivas de la Universidad Carlos III de Madrid sobre mecanismos de copia. El Pdf, un recurso de Informática para estudiantes universitarios, explora la gestión de memoria y la clase 'vecnum' en C++ avanzado, segón el esquema 'Mecanismos de copia' y 'Programación en C++ Vol. 2'.
Ver más43 páginas


Visualiza gratis el PDF completo
Regístrate para acceder al documento completo y transformarlo con la IA.
Uc3m Universidad Carlos III de Madrid Mecanismos de copia Programación en C++ Vol. 2 J. Daniel Garcia Universidad Carlos III de Madrid agosto de 2021 cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 1/28
Uc3m Universidad Carlos III de Madrid Licencia Creative Commons Cc Este trabajo se distribuye bajo licencia Atribución-NoComercial-SinDerivadas 4.0 Internacional (CC BY-NC-ND 4.0). Usted es libre de:
Bajo los siguientes términos:
cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 2/28
Uc3m Universidad Carlos III de Madrid
DEE Das cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 3/28
Uc3m Universidad Carlos III de Madrid Operaciones de copia generadas Por cada tipo definido por el usuario se generan de forma automática dos operaciones de copia:
cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 4/28Mecanismos de copia Copia por defecto Uc3m Universidad Carlos III de Madrid Operaciones de copia generadas Por cada tipo definido por el usuario se generan de forma automática dos operaciones de copia: Construcción de copia. Ty; Tx{y}; // Construcción de copia. Iniciación directa. T x = y; // Construcción de copia. Iniciación de copia.
cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 4/28Mecanismos de copia Copia por defecto Uc3m Universidad Carlos III de Madrid Operaciones de copia generadas Por cada tipo definido por el usuario se generan de forma automática dos operaciones de copia: Construcción de copia. T y; Tx{y}; // Construcción de copia. Iniciación directa. T x = y; // Construcción de copia. Iniciación de copia. Asignación de copia. T x, y; x = y; // Asignación de copia
Invocación (recursiva) de operaciones de copia para cada miembro. La copia de miembros tipos primitivos es la copia del valor. cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 4/28
Uc3m Universidad Carlos III de Madrid Vector numérico vecnum.hpp #ifndef VECNUM_NOCOPY_VECNUM_HPP #define VECNUM_NOCOPY_VECNUM_HPP #include #include class vecnum { public: vecnum() : tamanyo_ {0}, buffer_ {nullptr} explicit vecnum(int n) : tamanyo_ {n}, buffer_ {new double[n] {}} {} vecnum(std::initializer_list l); ~vecnum() { delete[] buffer _; } [[nodiscard] int tamanyo( const { return tamanyo _; } . . . cbnd J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 5/28
Uc3m Universidad Carlos III de Madrid Vector numérico vecnum.hpp . . . double operator[](int i) const { return buffer_[i]; } double & operator[] (int i) { return buffer_ buffer_[i]; private: int tamanyo _; double * buffer _; }; std :: ostream & operator << (std :: ostream & os, const vecnum & v); #endif// VECNUM_NOCOPY_VECNUM_HPP cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 6/28
Uc3m Universidad Carlos III de Madrid Implementación de vector numérico vecnum.cpp #include "vecnum.hpp" #include vecnum::vecnum(std::initializer_list l) : tamanyo_ {static_cast(l.size())}, buffer_ {new double[tamanyo_] {}} { std::copy(l.begin(), l.end(), buffer_); } std :: ostream & operator << (std :: ostream & os, const vecnum & v) { if (v.tamanyo()>0) { os << v[0]; } for(int i=1; i
Uc3m Universidad Carlos III de Madrid Usando vecnum main.cpp #include #include "vecnum.hpp" int main() { vecnum v1(5); v1[2] = 5.0; v1[4] = 3.5; vecnum v2 {v1}; std :: cout << "v1: (" << v1 << ")\n"; std :: cout << "v2: (" << v2 << ")\n"; return 0; } cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 8/28
Uc3m Universidad Carlos III de Madrid Usando vecnum main.cpp #include #include "vecnum.hpp" int main() { vecnum v1(5); v1[2] = 5.0; v1[4] = 3.5; vecnum v2 {v1}; std :: cout << "v1: (" << v1 << ")\n"; std :: cout << "v2: (" << v2 << ")\n"; return 0; } . Resultado de ejecución: v1: (0, 0, 5, 0, 3.5) v2: (0, 0,5,0,3.5) free(): double free detected in tcache 2 Abortado ( `core' generado) Problema: Doble liberación de memoria. cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 8/28
Uc3m Universidad Carlos III de Madrid $ valgrind ./vecnum_nocopy == 2710003 == Memcheck, a memory error detector == 2710003 == Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. == 2710003 == Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info == 2710003 == Command: . /vecnum_nocopy == 2710003 == v1: (0, 0, 5, 0, 3.5) v2: (0, 0, 5, 0, 3.5) == 2710003 == Invalid free() / delete / delete [] / realloc() == 2710003 == at 0x483D74F: operator delete [] (void*) (in /usr/lib/x86_64-linux-gnu/valgrind/ vgpreload_memcheck-amd64-linux. so) == 2710003 == by 0x1094BA: vecnum: :~ vecnum() (vecnum . hpp: 12) == 2710003 == by 0x109364: main (main.cpp:6) == 2710003 == Address 0x4dffc80 is 0 bytes inside a block of size 40 free'd == 2710003 == at 0x483D74F: operator delete [] (void*) (in /usr/lib/x86_64-linux-gnu/valgrind/ vgpreload_memcheck-amd64-linux. so) == 2710003 == by 0x1094BA: vecnum: :~ vecnum() (vecnum . hpp: 12) == 2710003 == by 0x109358: main (main. cpp: 10) == 2710003 == Block was alloc'd at == 2710003 == at 0x483C583: operator new [] (unsigned long) (in /usr/lib/x86_64-linux-gnu/valgrind/ vgpreload_memcheck-amd64-linux. so) == 2710003 == by 0x109455: vecnum : : vecnum(int) (vecnum. hpp: 10) == 2710003 == by 0x109295: main (main.cpp:6) == 2710003 == == 2710003 == HEAP SUMMARY : == 2710003 == in use at exit: 0 bytes in 0 blocks == 2710003 == total heap usage: 3 allocs, 4 frees, 73,768 bytes allocated $ cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 9/28
Uc3m Universidad Carlos III de Madrid Analizando resultado de valgrind Run: vecnum_nocopy x › Console Valgrind v InvalidFree 1 warning > H vecnum.hpp 1 warning v Invalid free() / delete / delete[] / realloc() 1 warning 0x483D74F operator delete[](void*) 0x1094BA vecnum ::~ vecnum() vecnum.hpp:12 0x109364 main main.cpp:6 Address 0x4dffc80 is 0 bytes inside a block of size 40 free'd 0x483D74F operator delete[](void*) [0x1094BA vecnum ::~ vecnum() vecnum.hpp:12 0x109358 main main.cpp:10 Block was alloc'd at 0x483C583 operator new[](unsigned long) ī 0x109455 vecnum :: vecnum(int) vecnum.hpp:10 0x109295 main main.cpp:6 Resultado similar con Address Sanitizer. cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 10/28
Uc3m Universidad Carlos III de Madrid Copia y liberación Problema: Al realizar la copia, se ha copiado la dirección del array. Los dos vectores estan compartiendo el mismo array. Se está desasignando dos veces un mismo bloque de memoria. tam v1: 5 0.0 0.0 5.0 0.0 3.5 v2: 5 cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 11/28
Uc3m Universidad Carlos III de Madrid
cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 12/28
Uc3m Universidad Carlos III de Madrid Constructor de copia El constructor de copia se invoca cuando se construye un objeto a partir de otro del mismo tipo. Toma un argumento referencia constante al tipo. vecnum(const vector &);
cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 13/28Mecanismos de copia Constructor de copia Uc3m Universidad Carlos III de Madrid Constructor de copia El constructor de copia se invoca cuando se construye un objeto a partir de otro del mismo tipo. Toma un argumento referencia constante al tipo. vecnum(const vector &); Se puede suprimir la generación automática del constructor de copia. vecnum(const vecnum &) = delete;
cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 13/28Mecanismos de copia Constructor de copia Uc3m Universidad Carlos III de Madrid Constructor de copia El constructor de copia se invoca cuando se construye un objeto a partir de otro del mismo tipo. Toma un argumento referencia constante al tipo. vecnum(const vector &); Se puede suprimir la generación automática del constructor de copia. vecnum(const vecnum &) = delete; El constructor de copia se invocara en definiciones del tipo: vecnum w {v}; // Iniciación directa vecnum w(v); // Iniciación directa. Sintaxis tradicional. vecnum w = v; // Iniciación de copia. No es asignación. cc J. Daniel Garcia. ARCOS@uc3m - josedaniel. garcia@uc3m. es - Twitter: @jdgarciauc3m 13/28