Autor
|
Tema: Ayuda con punteros (en C++) (Actualizacion constante con nuevas preguntas) (Leído 2,695 veces)
|
DarkSorcerer
Desconectado
Mensajes: 69
|
Bueno, soy novato, espero que me puedan ayudar. Estoy haciendo algunos ejercicios con punteros, cree una clase llamado "Auto" cuyos atributos son la marca, su patente (matricula) y el kilometraje, y en el main hice lo siguiente, cree 2 autos con asignacion automatica y 1 de forma dinamica, pero al momento de que se deben destruir al final del programa, me sale "RUN FAILED", ¿ a que se debera ?, yo en el destructor implemente de tal manera que informe de que se esta destruyendo el objeto. Les dejo el codigo. Es probable que use este mismo tema para hacer consultas, mi proximo objetivo es practicar con listas enlazadas, ya tengo experiencia pero en Java, pero ahora quiero practicar con punteros. NOTA 1: Cuando vean el codigo cuando el puntero auto3 apunta a auto2, ¿que sucede con los datos donde apuntaba auto3? , ¿ quedan para siempre en la memoria (a no ser que se reinicie) y tengo que usar delete ? NOTA 2: Si tengo algun error o tienen una sugerencia, estaria agradecido que me lo dijeran. Datos del auto 1
Marca: Patente: Kilometraje: 0
Datos del auto 2
Marca: Chevrolet Patente: ASDF Kilometraje: 300
Datos del auto3
Marca: Nissan Patente: QWERT Kilometraje: 500
Las direcciones de memoria de los autos son:
La direccion de memoria de auto 1 es: 0x22abe8 La direccion de memoria de auto 2 es: 0x22abd0 La direccion de memoria de auto 3 es: 0x22abcc
Ahora, auto3 va a apuntar a la direccion de auto2
La direccion de memoria de auto 3 es: 0x22abd0 La marca es: Chevrolet
Ahora, auto3 va a apuntar a la direccion de auto1
La direccion de memoria de auto 3 es: 0x22abe8 La marca es:
RUN FAILED (exit value 1,, total time: 734ms)
#include "Auto.h" #include <string> #include <iostream> using namespace std; Auto::Auto() { marca = ""; patente = ""; kilometraje = 0; } Auto::Auto(string m, string p, double k){ marca = m; patente = p; kilometraje = k; } Auto::Auto(const Auto& orig) { } Auto::~Auto() { cout <<"\nDestruyendo el auto ..."; } string Auto::getMarca(){ return marca; } string Auto::getPatente(){ return patente; } double Auto::getKilometraje(){ return kilometraje; }
#ifndef AUTO_H #define AUTO_H #include <string> #include <iostream> using namespace std; class Auto { public: Auto(); Auto(string m, string p, double k); Auto(const Auto& orig); virtual ~Auto(); string getMarca(); string getPatente(); double getKilometraje(); private: string marca; string patente; double kilometraje; }; #endif /* AUTO_H */
#include <cstdlib> #include "Auto.h" #include <iostream> using namespace std; int main(int argc, char** argv) { Auto auto1; Auto auto2("Chevrolet","ASDF",300); Auto *auto3 = new Auto("Nissan","QWERT",500); cout <<"Datos del auto 1\n"; cout <<"\nMarca: " << auto1.getMarca(); cout <<"\nPatente: " << auto1.getPatente(); cout <<"\nKilometraje: " << auto1.getKilometraje(); cout <<"\n\n"; cout <<"Datos del auto 2\n"; cout <<"\nMarca: " << auto2.getMarca(); cout <<"\nPatente: " << auto2.getPatente(); cout <<"\nKilometraje: " << auto2.getKilometraje(); cout <<"\n\n"; cout <<"Datos del auto3\n"; cout <<"\nMarca: " << auto3->getMarca(); cout <<"\nPatente: " << auto3->getPatente(); cout <<"\nKilometraje: " <<auto3->getKilometraje(); cout <<"\n\nLas direcciones de memoria de los autos son:\n"; cout <<"\nLa direccion de memoria de auto 1 es: " << &auto1; cout <<"\nLa direccion de memoria de auto 2 es: " << &auto2; cout <<"\nLa direccion de memoria de auto 3 es: " << &auto3; cout <<"\n\nAhora, auto3 va a apuntar a la direccion de auto2\n"; auto3 = &auto2; cout <<"\nLa direccion de memoria de auto 3 es: "<< auto3; cout <<"\nLa marca es: "<< auto3->getMarca(); cout <<"\n\nAhora, auto3 va a apuntar a la direccion de auto1\n"; auto3 = &auto1; cout <<"\nLa direccion de memoria de auto 3 es: "<< auto3; cout <<"\nLa marca es: "<< auto3->getMarca(); cout <<"\n"; delete auto3; return 0; }
|
|
« Última modificación: 17 Septiembre 2013, 11:35 am por DarkSorcerer »
|
En línea
|
|
|
|
eferion
Desconectado
Mensajes: 1.248
|
No puedes hacer un delete de un objeto que no ha sido creado con new. int main(int argc, char** argv) { Auto auto1; Auto auto2("Chevrolet","ASDF",300); Auto *auto3 = new Auto("Nissan","QWERT",500); // ... auto3 = &auto2; // ... auto3 = &auto1; // ... delete auto3; return 0; }
el delete está afectando al objeto auto1, ya que has modificado el puntero de auto3 para que apunte a la instancia de auto1. auto1 no ha sido creado con new y, por tanto, no se puede eliminar con delete. Además, para no dejar lagunas de memoria, deberías poner el delete antes de la línea "auto3 = &auto2;" delete auto3; auto3 = &auto2;
Una vez modificas el puntero "auto3" pierdes la referencia del objeto creado dinámicamente y, por tanto, desde ese momento es imposible eliminarlo y liberar esa parte de la memoria.
|
|
|
En línea
|
|
|
|
DarkSorcerer
Desconectado
Mensajes: 69
|
Gracias, se me olvidó ese detalle de que auto2 no fue creado por new y por eso no debo usar delete.
Ahora tengo otro problema, ahora me invente este problema, quise crear una clase que se llama Persona, sus atributos son el nombre, rut (en mi pais se refiere al numero de indentificacion) y la edad, tambie agregue un puntero que apunta a persona, con la intencion de que indicara a su hermano. Yo me imagine esto, cuando creo a una persona, se le asigna una direccion en la memoria, a si que como soy imaginativo, dije "aaahh, voy a imaginar que la direccion de la memoria es la direccion de su casa", de esta manera, cree 2 personas de manera dinamica, pero el problema me sucede cuando quiero preguntar por los hermanos atraves de una funcion getHermano, me sale un error. Les dejo el error que me sale en la ventana de comandos y el codigo (Estoy usando Netbeans 7.3) "/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf make[1]: Entering directory `/cygdrive/c/Documents and Settings/Administrador/Escritorio/C++/Repaso24' "/usr/bin/make" -f nbproject/Makefile-Debug.mk dist/Debug/Cygwin_4.x-Windows/repaso24.exe make[2]: Entering directory `/cygdrive/c/Documents and Settings/Administrador/Escritorio/C++/Repaso24' mkdir -p build/Debug/Cygwin_4.x-Windows/_ext/931385711 rm -f build/Debug/Cygwin_4.x-Windows/_ext/931385711/Persona.o.d g++ -c -g -MMD -MP -MF build/Debug/Cygwin_4.x-Windows/_ext/931385711/Persona.o.d -o build/Debug/Cygwin_4.x-Windows/_ext/931385711/Persona.o ../Repaso24/Persona.cpp ../Repaso24/Persona.cpp: In function ‘Persona Persona::* getHermano()’: ../Repaso24/Persona.cpp:54:12: error: ‘hermano’ was not declared in this scope nbproject/Makefile-Debug.mk:67: recipe for target `build/Debug/Cygwin_4.x-Windows/_ext/931385711/Persona.o' failed make[2]: *** [build/Debug/Cygwin_4.x-Windows/_ext/931385711/Persona.o] Error 1 make[2]: Leaving directory `/cygdrive/c/Documents and Settings/Administrador/Escritorio/C++/Repaso24' nbproject/Makefile-Debug.mk:60: recipe for target `.build-conf' failed make[1]: *** [.build-conf] Error 2 make[1]: Leaving directory `/cygdrive/c/Documents and Settings/Administrador/Escritorio/C++/Repaso24' nbproject/Makefile-impl.mk:39: recipe for target `.build-impl' failed make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2,, total time: 9s)
#include "Persona.h" #include <string> #include <iostream> using namespace std; Persona::Persona() { } Persona::Persona(string n, string r, int e){ nombre = n; rut = r; edad = e; hermano = 0; } Persona::Persona(const Persona& orig) { } Persona::~Persona() { cout <<"\n\nAniquilando a " << nombre; } string Persona::getNombre(){ return nombre; } string Persona::getRut(){ return rut; } int Persona::getEdad(){ return edad; } void Persona::setHermano(Persona *h){ hermano = h; } Persona Persona::*getHermano(){ return hermano; // Me sale un triangulo con signode exclamacion (o admiracion) }
#ifndef PERSONA_H #define PERSONA_H #include <string> using namespace std; class Persona { public: Persona(); Persona(string n, string r, int e); Persona(const Persona& orig); virtual ~Persona(); string getNombre(); string getRut(); int getEdad(); void setHermano(Persona *h); Persona *getHermano(); private: string nombre; string rut; int edad; Persona *hermano; }; #endif /* PERSONA_H */
#include <cstdlib> #include <iostream> #include "Persona.h" using namespace std; int main(int argc, char** argv) { Persona *persona1 = new Persona("Juan","123-K",25); Persona *persona2 = new Persona("Pedro","456-L",23); cout <<"Los datos de la persona 1 son:\n"; cout <<"\nNombre: " << persona1->getNombre(); cout <<"\nRut: " << persona1->getRut(); cout <<"\nEdad: " << persona1->getEdad(); cout <<"\nLa direccion de su casa es: " << persona1; cout <<"\n\nLos datos de la persona 2 son:\n"; cout <<"\nNombre: " << persona2->getNombre(); cout <<"\nRut: " << persona2->getRut(); cout <<"\nEdad: " << persona2->getEdad(); cout <<"\nLa direccion de su casa es: " << persona2; //Relacionando las dos personas como hermanos persona1->setHermano(persona2); persona2->setHermano(persona1); cout <<"\n\nEl hermano de la persona 1 se llama: "<< persona1->getHermano()->getNombre(); cout <<"\n\nEl hermano de la persona 2 se llama: "<< persona2->getHermano()->getNombre(); delete persona1; delete persona2; return 0; }
|
|
« Última modificación: 17 Septiembre 2013, 15:27 pm por Eternal Idol »
|
En línea
|
|
|
|
eferion
Desconectado
Mensajes: 1.248
|
Persona Persona::*getHermano(){ return hermano; // Me sale un triangulo con signode exclamacion (o admiracion) }
Es así Persona* Persona::getHermano(){ return hermano; }
|
|
|
En línea
|
|
|
|
DarkSorcerer
Desconectado
Mensajes: 69
|
Gracias, he aprendido mucho preguntando en el foro elhacker, por eso gracias a los que me han ayudado. Ahora, como habia dicho antes en este tema, me propuse ejercitar con listas enlazadas (estoy viendo estructura de datos en c++), en este caso, elegi usar "listas con doble nexo", algo asi NULL - O = O = O = O ....................... =O = O = O = O - NULL El nodo anterior y siguiente de cada nodo lo represento como punteros, el codigo que hice me funciona ni me da problemas, pero, tengo una pregunta que tiene que ver mas con la optimizacion de la memoria. Si bien, yo cree una lista de forma automatica (que deberia borrarse solo), ¿ que pasa con los nodos que siguiente y anterior creados de forma dinamica ?, ¿ Tendre que borrarlos uno por uno con delete ?, ¿existe algun modo de borrarlos de manera casi instantaneas ? Les dejo mi codigo #include "Nodo.h" #include <iostream> using namespace std; Nodo::Nodo(int n) { dato = n; siguiente = 0; anterior = 0; } Nodo::Nodo(const Nodo& orig) { } Nodo::~Nodo() { cout <<"\nDestruyendo nodo ...\n"; } void Nodo::setSiguiente(Nodo *s){ siguiente = s; } void Nodo::setAnterior(Nodo *a){ anterior = a; } int Nodo::getDato(){ return dato; } Nodo* Nodo::getSiguiente(){ return siguiente; } Nodo* Nodo::getAnterior(){ return anterior; }
#ifndef NODO_H #define NODO_H using namespace std; class Nodo { public: Nodo(int n); Nodo(const Nodo& orig); virtual ~Nodo(); void setSiguiente(Nodo *s); void setAnterior(Nodo *a); int getDato(); Nodo* getSiguiente(); Nodo* getAnterior(); private: int dato; Nodo *siguiente; Nodo *anterior; }; #endif /* NODO_H */
#include "Lista.h" #include "Nodo.h" #include <iostream> Lista::Lista() { head = NULL; tail = NULL; } Lista::Lista(const Lista& orig) { } Lista::~Lista() { cout <<"\nDestruyendo lista"; } void Lista::setHead(int num){ Nodo *nuevo = new Nodo(num); if(isEmpty()){ head = nuevo; //La cabeza apunta a la direccion del nuevo nodo tail = nuevo; //La cola tambien apunta a la direccion del nuevo nodo; }else{ nuevo->setSiguiente(head); //Nuevo nodo apunta hacia adelante, a la direccion de la ex cabeza head->setAnterior(nuevo); //La ex cabeza apunta hacia atras a la nueva cabeza head = nuevo; //La cabeza es apuntada hacia el nuevo nodo; } } Nodo* Lista::getHead(){ return head; } Nodo* Lista::getTail(){ return tail; } bool Lista::isEmpty(){ if(head == NULL){ return true; }else{ return false; } }
#ifndef LISTA_H #define LISTA_H #include "Nodo.h" class Lista { public: Lista(); Lista(const Lista& orig); virtual ~Lista(); void setHead(int num); Nodo* getHead(); Nodo* getTail(); bool isEmpty(); private: Nodo *head; Nodo *tail; }; #endif /* LISTA_H */
|
|
|
En línea
|
|
|
|
eferion
Desconectado
Mensajes: 1.248
|
Por cada new que pongas en tu código... tienes que poner otro delete. Lo que significa que la memoria no se va a liberar de forma automática y que cada nodo lo vas a tener que borrar tu de forma manual.
Puedes automatizar el proceso con un bucle... pero poco más.
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
[AYUDA] C# punteros
.NET (C#, VB.NET, ASP)
|
Miseryk
|
1
|
2,191
|
28 Febrero 2014, 21:06 pm
por kub0x
|
|
|
Ayuda con Punteros en C.
Programación C/C++
|
camv123
|
3
|
2,045
|
20 Abril 2014, 02:03 am
por camv123
|
|
|
Ayuda con Cstring y punteros
Programación C/C++
|
Zorzem
|
4
|
2,114
|
25 Junio 2014, 11:39 am
por Eternal Idol
|
|
|
Ayuda con punteros en C
« 1 2 »
Programación C/C++
|
snake_linux
|
12
|
5,439
|
27 Agosto 2015, 15:50 pm
por kondrag_X1
|
|
|
[ayuda] punteros en linklist
Programación C/C++
|
bash
|
1
|
1,772
|
15 Octubre 2016, 13:47 pm
por ivancea96
|
|