Error creando lista C++

Iniciado por d00ze13, 18 Diciembre 2013, 00:47 AM

0 Miembros y 2 Visitantes están viendo este tema.

d00ze13

Tengo un error a la hora de intentar acceder a un elemento de una lista en c++ y no se por que es, a ver si alguien me puede echar un cable please!
Pd: Solo tengo implementado para crear un nodo.

Código (cpp) [Seleccionar]

typedef struct tNodo {
   int num;
   tNodo *sig;
};
void insertar(tNodo *cab, int dato) {
   if (cab == NULL) {
       cab = new tNodo;
       cab->num = dato;
   }
}
int main()
{
   tNodo *cabecera = NULL;
   insertar(cabecera, 2);
   cout << cabecera->num << endl; //Aqui me peta

   return 0;
}

dato000

ummm creo que cometes unos errores, en primera no incluyes las librerias para correr el código, en segunda no usas el estandar std para el uso de entrada y salida.

en fin, te dejo el código y te explico lo que yo entiendo, pues mis concepto técnico aún lo estoy puliendo respecto a C++/C, pues siempre es complejo pero muy enriquecedor e interesante.

Código (cpp) [Seleccionar]

#include <iostream>
#include <cstring>

using namespace std;

struct tNodo {
   int num;
   tNodo *sig;
};

void insertar(tNodo *cab, int dato) {
   cab->num = dato;
}

int main()
{
   tNodo cabecera;
   memset(&cabecera, 0, sizeof(cabecera)); // En estructura no es posible instanciar, se usa asignación dinamica de memoria
   tNodo *p_cabecera;

   p_cabecera = &cabecera;
   insertar(p_cabecera, 2);
   //p_cabecera->num = 30;
   cout << p_cabecera->num << endl; //Aqui me peta
   return 0;
}


Mira lo primero que debes hacer es usar las librerias y el estandar de reserva de nombres, es decir, el namespace std. Por eso es que no te correo el cout.

Ahora respecto a los apuntadores a la estructura cabecera, no debes usarlo directamente, debes crear un apuntador que apunte (ya se ya se, valga la rebundancia) hacia la dirección de memoria creada por la estructura incial cabecera

Citar
tNodo cabecera;
tNodo *p_cabecera;
p_cabecera = &cabecera;

Así ya puedes usar el apuntador de la manera que te plazca sin errores de segmentación, pues lo que sucedia, o como lo veo, es que no habia memoria reservada para esa estructura, y por eso no era posible insertar ni imprimir datos, pues simplemente no habia nada en donde escribir la información.

Ahora lo que tu haces con NULL y eso, no es posible hacerlo con estructuras, como yo lo veo, leyendo por ahi, es que las estructuras no se comportan de la misma manera como las clases, pues aunque en c++ sean estimadas como clases con propiedades de caracter publico (quiero decir, que sus atributos siempre serán publicos por defecto, al contrario de crear una clase, que como se respete con un objeto sus atributos serán siempre privados por defecto), eso es digamos la versión corta, creo que alguien más puede extender un poco porque me interesa el saber esto también.



memset(&cabecera, 0, sizeof(cabecera));


Es por ello que lo que debe hacerse es reservar memoria dinamica del tamaño de la estructura para determinar que no hay nada ahí, o algo así, no se como podría explicarlo mejor, es como para hacerlo, necesitas de malloc o de memset (biblioteca cstring en C++ o string.h en C) de un tamaño determinado y luego le indicas que es vacio, pero es un vacio del tamaño de la estructura que tienes.

http://stackoverflow.com/questions/2022425/comparing-structs-to-null
http://stackoverflow.com/questions/6891720/initialize-reset-struct-to-zero-null

Bueno creo que eso seria todo, suerte con tu trabajo.

PD: estamos hablando de estructuras (struct) no de listas (list) son cosas completamente diferentes.  :silbar: :silbar:



rir3760

Cita de: d00ze13 en 18 Diciembre 2013, 00:47 AMTengo un error a la hora de intentar acceder a un elemento de una lista en c++
Hay dos errores en el programa.

El primero es el uso de typedef, en C++ no es necesario (con usar la etiqueta basta) y su forma no es la correcta, en C (donde si es necesario) seria así:
typedef struct nodo {
   int num;
   struct nodo* sig;
} tNodo;


El segundo y mas importante: el argumento de la función "insertar" se pasa por valor y el parámetro "cab" es una variable local (única) a la función, puedes hacer lo que quieras con ella sin afectar el valor de la variable "cabecera" de la función main.

Para solucionarlo solo debes cambiar la declaración y definición de la funcion "insertar" para indicar el uso de una referencia:
Código (cpp) [Seleccionar]
#include <iostream>
using namespace::std;

struct tNodo {
   int num;
   tNodo* sig;
} ;

void insertar(tNodo*& cab, int dato);

int main()
{
   tNodo* cabecera = 0; // En C++ lo politicamente correcto es 0
   insertar(cabecera, 2);
   cout << cabecera->num << endl;
   delete cabecera;
   
   return 0;
}

void insertar(tNodo*& cab, int dato)
{
   if (cab == 0){
      cab = new tNodo;
      cab->num = dato;
   }
}


Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language

d00ze13

Muchas gracias a los dos por las explicaciones tan buenas! me ha quedado muy claro!