Errores y magia en vector<> C++

Iniciado por Kaxperday, 6 Julio 2015, 15:29 PM

0 Miembros y 1 Visitante están viendo este tema.

Kaxperday

Bueno tras perder todo lo que acabo de escribir iré al grano.

Tengo una clase que contiene 2 vectores, uno contiene la lista de ips y otro la lista de macs de la red, a ips[2] le correspondería la mac macs[2]. Fácil.

Ambos vectores son de tipo u_char*. Antes que nada os dejo el codigo:

La clase es lista_usuarios:

Código (cpp) [Seleccionar]
class lista_usuarios
{
public:
vector<u_char*> ips;//LA p**a *****.
vector<u_char*> macs;
void almacena_usuario(u_char* ip, u_char* mac);
};

void lista_usuarios::almacena_usuario(u_char* ip, u_char* mac)
{
int cont = 0, cant = 0;//diferenciar win32 win64 if def ifndef

if (sizeof(ip) == 4 && sizeof(mac) == 4)
{
if (ips.size() == 1)
{
printf("\n");
for (int k = 0; k < 4; k++)
{
printf("%x", ips[0][k]);
}
}
//CLARO MISTERIOSAMENTE EL VECTOR VALE LO MISMO QUE IP NO ALMACENA UNA p**a *****
for (int i = 0; i < ips.size(); i++)
{
for (int k = 0; k < 4; k++)
{
//printf("%x", ip[k]);
}
printf("-");
for (int k = 0; k < 4; k++)
{
//printf("%x", ips[i][k]);
}
printf("\n");


for (int j = 0; j < 4; j++)
if (ip[j] == ips[i][j])
cont++;


for (int j = 0; j < 6; j++)
if (mac[j] == macs[i][j])
cant++;
}
//printf("\nCont: %d, Cant: %d\n", cont, cant);
if (cont != 4 && cant != 6)
{
printf("entra\n\n", cont);
/*for (int k = 0; k < 4; k++)
{
printf("%x", ip[k]);
}
printf(" - ");
for (int k = 0; k < 6; k++)
{
printf("%x", mac[k]);
}
system("pause");*/
ips.insert(ips.begin(), ip);
macs.insert(macs.begin(), mac);
}
}
}


La llamada a la función es así:

lista.almacena_usuario(ip,mac);

Yo le paso la ip y la mac del host, ambas son u_char*.

Ahora comienza la MAGIA del programa, cuando esto:

printf("%x", ips[0][k]);

Muestra cada vez una cosa distina, es decir el vector de las ips su primer elemento (ips[0]) que contiene 4 valores u_char que corresponden a la IP, VEMOS que en cada llamada toma una IP distinta que casualmente es justo la que ha recibido, luego el vector siempre tiene 1 elemento, que es cuando cont=0 la primera vez (al no haber ips/mac entra porque no hay otra igual a la suya), si hay igual no se añade y saldría.

Salida: (muestra el contenido del primer elemento del vector de ips como vemos su valor se sobreescribe ¿porque? no lo sé)

ac1aab0-

ac1aa42-

ac1aa44-

ac1aab0-

ac1aa42-

ac1aa44-

ac1aa44-

ac1aa42-

ac1aa44-

ac1aab0-

ac1aa42-

ac1aa44-

ac1aa44-

ac1aa42-

ac1aab0-

ac1aab0-

ac1aa44-

ac1aab0-

ac1aa42-
tam: 1
ac1aa42::5c2e59caddeb


Al final muestra las IPs de la lista y su MAC asociada, en este caso 1 solo, ¿porque? porque la lista solo tiene un elemento, ¿porque? porque se sobreesribe...

DesesperanT.

OJO que si pruebo a hacer simplemente esto:

lista.ips.insert(lista.ips.end(), ip);
lista.macs.insert(lista.macs.end(), mac);


La lista me sale con 40 elementos todos iguales, a pesar de que al insertar inserto distintos elementos, ¿esto que broma es?
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

Código (cpp) [Seleccionar]
ips.insert(ips.begin(), ip);
macs.insert(macs.begin(), mac);


Eso, nunca, salvo que realmente lo quieras así, claro.

Estás metiendo una dirección. Esa dirección, al acabar el programa, puede desaparecer (tú sabrás qué haces con ella). Lo que has de hacer es malloc() y copiar lso bytes.


Además, te recomendaría usar push_back, para evitar tener que desplazar todo el array internamente.

Y si es posible, sería mejor que hicieras una estructura, que sea lo que guardes en el vector. En esa estructura, en constructor y destructor es donde deberías copiar y liberar memoria.

Kaxperday

#2
Ooohhhhhg, está claro que esto es una chapuza:

Código (cpp) [Seleccionar]
vector<u_char*> ips;
vector<u_char*> macs;


Ahora bien, crearé una estructura y trataré de almacenar los datos en ella creo que realmente es lo mejor (haber si me acuerdo como iba eso del next etc XD), y luego ya veré que tal me va. Y lo pondré por aquí.

¿que tal una estructura así?

struct hosts
{
u_char ip[4];
u_char mac[6];
hosts* next;
};


Es que despues de lo que he programado y que me falle al final... otra vez a cambiarlo :D :D :D :D :D :D :D

Edito: ¿No sabrás como se hacia para añadir un nuevo elemento a la lista con el malloc?
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

Kaxperday

#3

struct host
{
u_char ip[4];
u_char mac[6];
host* next;
};

class lista_usuarios
{
public:
struct host *usuarios = NULL;
void insertar_host(u_char* ip, u_char* mac);
};

void lista_usuarios::insertar_host(u_char* ip, u_char* mac)
{
int cont = 0, cant = 0;

//diferenciar win32 win64 if def ifndef comprobar si esta corrupto
while (usuarios != NULL)
{
for (int j = 0; j < 4; j++)
if (ip[j] == usuarios->ip[j])
cont++;
for (int j = 0; j < 6; j++)
if (mac[j] == usuarios->mac[j])
cant++;
usuarios = usuarios->next;
}

if (cont != 4 && cant != 6)
{
usuarios->next = (host*)malloc(sizeof(host));
for (int j = 0; j < 4; j++)
usuarios->ip[j] = ip[j];
for (int j = 0; j < 6; j++)
usuarios->mac[j] = mac[j];
}
}


Eso tengo hasta ahora, no se si tengo bien lo de añadir nuevo host usando el malloc.

.. me sale que ha dejado de funcionar y no puedo depurarlo porque me faltan los PDBs  :-X :-X :-X
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

struct host *usuarios = NULL;

Como dato, en C++ no necesitas poner "struct " al principio.

Puedes hacer un vector<host> o un list<host>. Ya que en la estructura hay punteros, deberías hacer constructor, constructor de copia y destructor. Si no los haces, entonces deberías hacer una list<>, ya que el vector andará copiando los elementos.

Ya que pretendes hacer una lista, pues list<host> te va a ahorrar todo lo relacionado con la lista.

Y otra cosa importante: en C++, y especialmente si usas clases y estructuras, evita usar malloc(), y usa new. Malloc solo consigue memoria. New además, llama a los constructores.

Aquí es donde te pregunto: ¿Quieres seguir con C, o con C++?

De hecho, juraría que vi en otro tema que usabas cout. Pero aquí solo veo printf. Si bien se pueden mezclar sin ningún problema, pues bueno.

Kaxperday

#5
Ohhhhhhhgggg, eso quiere decir que otra vez a cambiarlo todo, usaré vector<host> y a ver........ si...... lo consigo, muchas gracias.

La verdad aprendí C, no C++, sin embargo son casi iguales así que no tengo apenas problemas, otra cosa que me acuerde de C XDD

Saludos.

Edito: ¿Como insertaría la ip y la mac en la lista despues?

Edito SOLUCIONADO!!!!

Ya me muestra todas las jodidas ips y macs sin problemas de la reeed!!!.

Código (cpp) [Seleccionar]
void lista_usuarios::insertar_host(u_char* ip, u_char* mac)
{
int cont = 0, cant = 0;

//diferenciar win32 win64 if def ifndef comprobar si esta corrupto

for (int i = 0; i < usuarios.size();i++)
{
for (int j = 0; j < 4; j++)
if (ip[j] == usuarios[i].ip[j])
cont++;
for (int j = 0; j < 6; j++)
if (mac[j] == usuarios[i].mac[j])
cant++;
}

if (cont != 4 && cant != 6)
{
host usuario;
for (int j = 0; j < 4; j++)
usuario.ip[j] = ip[j];
for (int j = 0; j < 6; j++)
usuario.mac[j] = mac[j];
usuarios.insert(usuarios.end(), usuario);
}
}


Gracias socio, siempre en deuda.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

Como dato, puedes cambiar
usuarios.insert(usuarios.end(), usuario);
por
usuarios.push_back(usuario);

Kaxperday

Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.