[C con Clase] otro error mysql-c
Steven Davidson
steven en conclase.net
Mie Jun 13 19:31:50 CEST 2007
Hola Duna,
El pasado 2007-06-13 10:53:12, Duna escribió:
D> Hola.
D> No sé qué me pasa, pero estoy teniendo muchos problemas con la conexión
D> entre estructuras en c y asociar los datos que obtengo de la base de datos
D> mysql.
D> os pongo el código y el error a ver si alguie me puede ayudar, ya que se lo
D> agradecería muchiiiiiiiiiisimo...
Veamos la parte que interesa.
D> struct final_l_titulo
D> {
D> char* titulo;
D> struct final_l_titulo * next;
D> };
[CORTE]
D> if((res1 = mysql_store_result(base)))
D> {
D> i = (int) mysql_num_rows(res1);
D> j = (int) mysql_num_fields(res1);
D> printf ("\nEl número de resultados es: %d\n", i);
D> columna = mysql_fetch_fields(res1);
D> if (i!=0)
D> {
D> primero=NULL;
D> anterior=NULL;
D> for(l = 0; l < i; l++)
D> {
D> consulta1= (final_l_titulo *)malloc (sizeof
D> (final_l_titulo));
D> row = mysql_fetch_row(res1);
D> lon = mysql_fetch_lengths(res1);
D> printf ( "Registro no. %d", l+1);
D> // Mostrar cada campo y su longitud:
D> k=0;
D> consulta1->titulo = row[k]; AQUI ES
D> DONDE ME DA EL ERROR
Esto es normal. Ten presente que el campo de 'titulo' es un puntero y 'row[]' también lo es. Esto significa que se copian las direcciones de memoria y no el contenido de la cadena. Lo que deberías hacer es crear memoria dinámicamente para 'titulo'. Por ejemplo,
consulta1->titulo = (char *) malloc( strlen(row[k])+1 );
strcpy( consulta1->titulo, row[k] );
Obviamente, tendrás que liberar la memoria de cada 'titulo' antes de liberar la memoria de cada nodo de la lista enlazada.
D> printf ("\n%s", consulta1->titulo);
D> printf (" ");
D> k++;
D> consulta1->next=NULL;
D> if (primero == NULL)
D> primero=consulta1;
D> else
D> anterior->next=consulta1;
Esto es un error, porque 'anterior' al comienzo es un puntero nulo. Aquí el sistema operativo te dará otro error. La solución es asignar el primer nodo a 'anterior' para que apunte a un nodo válido. Esto es,
if( !primero )
primero = anterior = consulta1;
else
anterior->next = consulta1;
anterior = consulta1;
D> anterior=consulta1;
D> }
D> }
D> }
D> if (i != 0)
D> {
D> consulta1->next=NULL;
D> consulta1=primero;
D> }
D> if (i==0)
D> {
D> consulta1=NULL;
D> }
Primeramente, estas condiciones son mutuamente exclusivas y por tanto deberías expresarlas como 'if/else'. En segundo lugar, no estoy muy seguro de por qué quieres molestarte con 'consulta1'. Lo que realmente te interesa es el comienzo de la lista enlazada; es decir, el puntero 'primero'.
Si retornas 'primero', puedes eliminar todas estas condiciones.
D> //mysql_free_result(res1);
Debes liberar la memoria invocando esta función.
D> mysql_close(base);
D> return (consulta1);
D> }
D> y el error que me da cuando hago un debug es este:
D> Unhandled exception in proyecto.exe : 0x000000005 Access violation
Este error casi siempre se refiere a un problema de direcciones de memoria: punteros inválidos, memoria liberada pero usada posteriormente, etc..
Espero que todo esto te ayude.
Steven
Más información sobre la lista de distribución Cconclase