[C con Clase] otro error mysql-c

Steven Davidson steven en conclase.net
Mar Jun 19 20:03:05 CEST 2007


Hola Duna,

El pasado 2007-06-19 10:42:58, Duna escribió:

D> Hola Steven.
D> Muchas gracias por tu ayuda, pero me sigue saliendo el mismo error, es como
D> si la estructura estiviera mal definida.
D> El caso es que lo de
D> consulta1->titulo = row[k];
D> Ya lo he hecho en otras estructuras y me ha asignado bien el valor, pero no
D> entiendo por qué en este caso lo hace mal

Sólo porque aparente funcionar en otras partes no implica que su manipulación sea correcta. Esta "regla" es cierta especialmente cuando estamos tratando punteros. Si no tenemos cuidado, los punteros son algo traicioneros y peligrosos. Por eso dije en mi correo-e anterior que copies los contenidos apuntados y no los punteros en sí.

D> Me sigue dando el error en el titulo al asignar lo que sea, y no entiendo
D> por qué. Me sigue dando el error de access violation.
D> Alguna idea más?

Cuando sucede este error es que tenemos algún problema de memoria que en el 99% de los casos tiene que ver con punteros. Analizando el problema que tienes, vemos que existen 4 punteros, de entre los cuales 3 pueden ser los cuplabls del error. Tenemos:
- 'consulta1' que es un puntero a un nodo,
- 'titulo' que es un puntero a 'char', para describir una cadena de caracteres,
- 'row' que es de tipo 'MYSQL_ROW' el cual se define como un puntero a 'char *'.

Si cualquiera de estos punteros es "basura" o es nulo, vas a tener el error que mencionas en tiempo de ejecución. Por lo tanto, necesitamos comprobar que los punteros recibidos no sean nulos y cuidar que no contengan "basura"; o sea, que las direcciones de memoria sean válidas. En el caso de 'row', no hace falta comprobar su validez, porque conocemos la cantidad de filas al invocar 'mysql_num_rows()'. Aún así, sugiero comprobar el resultado de 'mysql_fetch_row()', ya que estamos teniendo errores en el programa. Podríamos hacer lo siguiente:

if( !consulta1 )
  fputs( "ERROR: consulta1 es nulo", stderr );

if( !row )
  fputs( "ERROR: row es nulo", stderr );
else if( !row[k] )
  fputs( "ERROR: row[k] es nulo", stderr );
...

Esto es para determinar quién cause el problema.

D> Me pasa lo mismo con otra estructura, pero que tiene un int y hago:
D> consulta3->cl= atoi[row(K)]

Tal cual esto no compilaría. Supongo que lo escribiste de memoria y con "prisas". Debe ser:

consulta3->cl = atoi( row[k] );

D> Y me funciona en otras estructuras pero en esa no, quizás es que hay algo
D> que está mal...

Nuevamente, comprueba que 'consulta3' no sea nulo y que apunte a una dirección de memoria válida. Lo mismo sucede con 'row' y con 'row[k]'.


También ten presente que las filas obtenidas al invocar 'mysql_fetch_row()' de por sí no están terminadas en cero. Dicho de otra manera, las filas implícitamente no son cadenas de caracteres terminadas con un carácter nulo. Es posible que esto sea el problema. Por ello invoca 'mysql_fetch_lengths()' para conocer la cantidad de bytes para cada fila. Esto lo haces en tu programa, pero no haces nada con este valor guardado en la variable 'lon'.

Reiterando lo que dije en mi correo-e anterior, crea memoria para 'consulta1'->titulo'. Luego, copia los caracteres necesarios desde la fila. Por último agrega el carácter nulo al final, para asegurarnos. Esto sería,

consulta1->titulo = (char *) malloc( lon+1 );  /* 'char' es siempre 1 byte */

/* Quizá sea mejor usar 'memncpy()', pero para este caso 'strncpy()' sirve */
strncpy( consulta1->titulo, row[k], lon );
consulta1->titulo[lon] = 0;  /* Agregamos el carácter nulo al final */


Espero que esto te ayude.

Steven


Más información sobre la lista de distribución Cconclase