| Ver tema anterior :: Ver siguiente tema | | Autor | Mensaje |
|---|
GoldOozaru
Registrado: 21 Jun 2007 Mensajes: 55
| Publicado: 27/08/2007 10:23 am | | | Título: AYuda con algoritmo y memoria |
| Por favor me podrian ayudar a revisar esta funcion si no es mucha molestia y ayudarme a encontrar el problema por el cual funciona para texto pequeño pero no para textos grandes.
Basicamente recoge una cadena de texto letra por letra de bluetooth y eso lo descompone y saca los clientes y pedidos, eltexto tine la forma !clicod|nombre|cod|cant|cod|cant|cod|cant!clicod|nombre|cod|cant|cod|cant|cod|cant|? esto funciona para 2 o 3 clientes pero para mas clientes ya n funciona se reinicia la maquina.
| Código: |
int cargarRuta () { char Pedido [13]="\0";//guarda temporalmente el articulo que ira al pedido char codNom [8]="\0";//es el codigo del cliente en la ruta char letr [2]="\0"; //char* temp=NULL; int totalRuta=0; int timeout=0; int i=0; int verifPed=0;//identificador para saber cuando se esta leyendo el articulo de un pedido int verifRut=0;//identificador para saber cuando se esta leyendo un cliente de la ruta
finCarga=0;//cambiar por 0 para que reciba la informacion
limpiarDBRuta (); /* printf ("\fEscuchando\nconexion..."); WaitForKey (); */ abrirServidor (); printf ("\fEsperando a\nconfirmar la conexion..."); while (blt_is_connected ()==FALSE && timeout<100) { delay (2); timeout+=20; idle (); } printf ("\fRecibiendo...\n\nEspere por\nfavor"); while (finCarga==0) { letraRecibida=recibirCharBT (); //printf ("%c", letraRecibida); if (letraRecibida=='!') { finCarga=1; verifRut++; } } printf ("\ffincarga=0"); WaitForKey (); finCarga=0; while (finCarga==0) { letraRecibida=recibirCharBT (); if (letraRecibida=='?') { finCarga=1; } else if (letraRecibida!=-1) { if (letraRecibida=='|') { verifPed++; } else if (letraRecibida=='!') { verifRut++; } if (verifPed!=2) { if (verifRut==1) { if (letraRecibida!='!') { letr [0]=(char)letraRecibida; letr [1]='\0'; strcat (Cliente, letr); } } else { letr [0]=(char)letraRecibida; letr [1]='\0'; strcat (Pedido, letr); } } if (verifPed==2) { verifPed=0; if (verifRut==1) { //OJO: cierra la BDD para el pedido del cliente anterior cerrarDBGen (); Cliente [strlen (Cliente)]='\0'; printf ("Agregando .%s. a la ruta...", Cliente); WaitForKey (); abrirDBRuta (); agregarRegistroClienteTexto (Cliente); cerrarDBRuta (); totalRuta++; for (i=0;i<strlen (Cliente);i++) { if (Cliente [i]=='|') i=strlen (Cliente); codNom [i]=Cliente [i]; } codNom [i]='\0'; limpiarDBGen (codNom, 13); strcpy (Cliente, "\0");
abrirDBGen (codNom, 13); cerrarDBGen (); verifRut=0; } else { Pedido [strlen (Pedido)]='|'; Pedido [strlen (Pedido)]='\0';
abrirDBGen (codNom, 13); agregarRegistroGenTexto (Pedido); cerrarDBGen (); Pedido[0]='\0'; Pedido[1]='\0'; Pedido[2]='\0'; Pedido[3]='\0'; Pedido[4]='\0'; Pedido[5]='\0'; Pedido[6]='\0'; Pedido[7]='\0'; Pedido[8]='\0'; Pedido[9]='\0'; Pedido[10]='\0'; } } } } cerrarServidor (); return totalRuta; }
|
|
| | Volver arriba | |  | mamntc02
Registrado: 30 Abr 2007 Mensajes: 242
| Publicado: 28/08/2007 2:15 am | | | Título: |
| Hola,
Lo más probable es q tengas algún desbordamiento de memoria, o algún memory leak q te haga augmentar la memoria indefinidamente. Repasa q todo lo q reserves lo vayas liberando. También he visto q usas alguna variable (p.ej. letraRecibida) q no está declarada, al menos en la función. Otra cosa, aunque no creo q sea ningún problema, una cadena no se acostumbra a inicializar a 0 con comillas dobles, sino con simples o asignandole 0 directamente:
| Código: | char Pedido [13]="\0"; // Seguro q se puede hacer pero jamás lo he visto así
char Pedido[13]='\0'; // Así es más correcto char Pedido[13]={0}; //Es la mejor manera (creo)
|
Vigila también q la condición para salir de los while's sea correcta, y q compruebes q si noy hay datos a recibir (no sé si de servidor o de BBDD) el programa finalice. Por lo demás no te puedo ayudar en mucho más, a no ser q des un ejemplo de uso completo. Personalmente te recomiendo q lo debugges para ver donde peta exactamente, y en caso de no poder usar un debugger, utiliza trazas para determinar q está haciendo, por donde y con qué datos.
Saludos. |
| | Volver arriba | |  | rir3760

Registrado: 01 Oct 2004 Mensajes: 3657 Ubicación: Mexico
| Publicado: 28/08/2007 7:24 am | | | Título: |
| Cuando se declara e inicializa un array de caracteres se puede utilizar una de las dos formas:
| Código: | char cadena[4] = {'x', 'y', 'z', '\0'};
/* o tambien */
char cadena[4] = "xyz"; |
Se prefiere la segunda por ser mas corta y clara, en esta el caracter '\0' se agrega de forma automatica al final de la cadena y no es necesario añadirlo manualmente, en otras palabras esto:
| Código: | char cadena[10] = "\0" |
Es lo mismo que:
| Código: | char cadena[10] = {'\0', '\0'}; |
Un saludo _________________ The capacity to learn is a gift; The ability to learn is a skill; The willingness to learn is a choice. -- Rebec of Ginaz |
| | Volver arriba | |  | | cheroky
Registrado: 22 Sep 2005 Mensajes: 1372 Ubicación: En ecx esperando un call
| Publicado: 28/08/2007 10:07 am | | | Título: |
| La dos formas de rellenar el array dan el mismo resultado pero, el "objeto" la cadena literal se mantiene en el programa (area de datos).
S2. _________________ - Explícito es mejor que implícito. - Simple es mejor que complejo. - Complejo es mejor que complicado. - Plano es mejor que anidado. - Ralo es mejor que denso.
Ultima edición por cheroky el 28/08/2007 12:18 pm; editado 1 vez |
| | Volver arriba | |  | GoldOozaru
Registrado: 21 Jun 2007 Mensajes: 55
| Publicado: 28/08/2007 11:12 am | | | Título: |
| Gracias por las respuestas, pues les comento que el problema no es un loop infinito ya que la ejecucion de la funcion es normal hasta la ultima linea de codigo, es decir se ejecuta normalmente y cuando va a salir de la funcion, es decir justo al return se traba. Yo me he dado cuenta que se traba al regresar de la llamada de la funcion.
Ya he cambiado los arreglos por punteros y estoy usando el malloc y el free pero me da lo mismo.
cuando mando aproximadamente unos 3 clientes funciona bien, pero a los 9 clientes ya se traba y debe funcionar bien para 90 asi que estoy en ese dilema y solo tengo una hora diaria de internet.
En otra ocacion me paso lo mismo y tuve que copiar el codigo de la funcion y ponerlo en lugar de la llamada de la fucion y funciono como si el problema se diera unicamente por usar una funcion. |
| | Volver arriba | |  | rir3760

Registrado: 01 Oct 2004 Mensajes: 3657 Ubicación: Mexico
| Publicado: 28/08/2007 3:21 pm | | | Título: |
| | GoldOozaru escribió: | | Ya he cambiado los arreglos por punteros y estoy usando el malloc y el free pero me da lo mismo. |
Esto sugiere que el problema no esta relacionado con el uso de memoria.
| GoldOozaru escribió: | | En otra ocacion me paso lo mismo y tuve que copiar el codigo de la funcion y ponerlo en lugar de la llamada de la fucion y funciono como si el problema se diera unicamente por usar una funcion. |
Esto sugiere que el problema tal vez este relacionado con un conflicto de nombres, esto es, tener variables con el mismo nombre en diferentes bloques (y como consecuencia con diferente ambito o alcanze).
Un saludo _________________ The capacity to learn is a gift; The ability to learn is a skill; The willingness to learn is a choice. -- Rebec of Ginaz |
| | Volver arriba | |  | | GoldOozaru
Registrado: 21 Jun 2007 Mensajes: 55
| Publicado: 29/08/2007 6:54 am | | | Título: |
| mmm, la verdad es que solo he cambiado unos 3 char [] por char *
Haber les suplico ayuda en esto, le explico mas a detalle. Mi equipo solo tiene 512 kb de ram, de los 512 kb se usa una cantidad para un ram disk que hace las funciones de disco duro, sin embargo en la documentacion del dispositivo me dice esto:
| Cita: | The file system emulates a disk drive in RAM. The file system has a flat directory structure, like in MS-DOS version 1.00. The file names are in MS-DOS 8.3 format, that is from 1 to 8 characters for the name, and 3 characters or less for the extension. The maximum number of files that can exist in the file system is 50. The maximum number of files that can be open at the same time is 17, plus stdin, stdout and stderr. The file system does not store time and date information. There is not a hard-coded boundary between memory used for the file system and memory used for the memory pool. The file system and the memory pool share the same memory space. The advantage is that memory can be allocated to files or allocated to the application by malloc() exactly as needed. When a file is stored in the file system, blocks are dynamically allocated as the file is growing. Each block has a fixed size, the default 'sector' size of the RAM disk. Because of the dynamic nature of the file system it relies heavily on malloc(). This also means that the file system can be corrupted, when malloc() and free() are used incorrectly. So, the application developer is advised to be careful when using free() and malloc().
|
Entonces no estoy muy seguro de algunas cosas, por ejemplo que exactamenter hace malloc, he leido que devuelve un puntero a una direccion de memoria donde alcance de manera contigua lo que se desee grabar, sin embrgo no tengo idea si ese espacio de memoria se vuelve exclusivo o puede ser accedido por fallos en otros punteros, tampoco se que hace exactamente en free, se que libera la memoria para que lo use otras variables, pero esto significa acaso que sin el free la memoria estaab exclusivamene reservada, tampoco se que pasa con el punero luego de que se libera, se hace NULL, no le pasa nada, o yo no se.
Yo se que es mucho pedir pero sera que alguien podria darle una revisadita a mi codigo completo y decirme u orientarme acerca de que problemas tengo? |
| | Volver arriba | |  | rir3760

Registrado: 01 Oct 2004 Mensajes: 3657 Ubicación: Mexico
| Publicado: 29/08/2007 8:01 am | | | Título: |
| Lo primero que debes hacer para encontrar la mayor cantidad posible de errores es compilar tu programa en el modo mas estricto posible, como hacerlo depende del compilador que estes utilizando y esto debe estar descrito claramente en su documentacion.
No es posible verificar el codigo (al menos no totalmente) ya que hay varias variables que no muestras como estan declaradas asi como tampoco que valore iniciales tienen. Las llamadas a funcion son igual de problematicas ya que al parecer estas utilizando un motor de base de datos pero no indicas cual, con suerte alguno de los usuarios de los foros te pueda ayudar con esa parte especifica de tu programa.
Esta sentencia en tu programa es innecesaria:
| Código: | Cliente[strlen (Cliente)] = '\0'; |
Ya que la funcion strlen devuelve el numero de caracteres que componen la cadena de texto sin incluir el caracter '\0', utilizar este valor de retorno como indice resulta en la ubicacion del mentado caracter.
Mas claro con un ejemplo:
| Código: | char cadena[] = "hola"; /* ==> h, o, l, a, '\0' */ char int longitud;
/* ... */
longitud = strlen(cadena); /* longitud == 4 */
cadena[longitud] = '\0'; /* ** esto ultimo es lo mismo que: ** ** cadena[4] = '\0'; ** ** Y en este caso es redundante porque en la posicion ** cuatro *YA ESTA ALMACENADO EL '\0'* */ |
Lo que si es un error es:
| Código: | Pedido[strlen (Pedido)] = '|'; Pedido[strlen (Pedido)] = '\0';
abrirDBGen (codNom, 13); agregarRegistroGenTexto (Pedido); cerrarDBGen (); |
Esto porque toda cadena se reconoce por el caracter '\0' que marca el fin de esta. Cuando tu haces:
| Código: | Pedido[strlen (Pedido)] = '|';" |
Eliminas ese indicador y la siguiente llamada a strlen te va a devolver un valor incorrecto:
| Código: | Pedido[strlen (Pedido)] ... ; |
Esa posicion ya no es correcta, incluso tal vez no sea parte del array "Pedido" y ese bloque de instrucciones la primera vez que se llame (o eventualmente) debe causar que tu programa no funcione correctamente.
Un saludo _________________ The capacity to learn is a gift; The ability to learn is a skill; The willingness to learn is a choice. -- Rebec of Ginaz |
| | Volver arriba | |  | GoldOozaru
Registrado: 21 Jun 2007 Mensajes: 55
| Publicado: 29/08/2007 2:06 pm | | | Título: |
| Ok, si, pensandolo bien si era algo ilogico lo que hacia porque quitaba el fin de linea. Bueno no se si para bien o para mal pero ciertamente es un incoveniente porque el equipo se daño al correr esa funcion y estamos a la espera de otro.
Ya le corregi usando el strcat (Pedido, "|\0") o al menos eso asumo porque a no tengo como probar, con respecto alo de complar del modo mas estricto posible pues solo tengo un modo de compilacion y si tengo algunos warnings pero son cosas que considero son infignificantes. |
| | Volver arriba | |  | | GoldOozaru
Registrado: 21 Jun 2007 Mensajes: 55
| Publicado: 01/09/2007 4:58 pm | | | Título: |
| Bueno lo arregle al codigo y quedo asi:
| Código: | int cargarRuta () { int finCarga=0; char *Pedido=NULL;//guarda temporalmente el articulo que ira al pedido char *codNom=NULL;//es el codigo del cliente en la ruta char letr [2]="\0"; int totalRuta=0; int timeout=0; int ct=0;
/* printf ("\fAbriendo servidor"); WaitForKey (); */ abrirServidor (); Cliente=(char*)malloc (29*sizeof (char)); memset( Cliente, '\0', sizeof( Cliente )); codNom=(char*)malloc (8*sizeof (char)); memset( codNom, '\0', sizeof( codNom )); Pedido=(char*)malloc (20*sizeof (char)); memset( codNom, '\0', sizeof( Pedido )); limpiarDBRuta (); printf ("\fEsperando a\nconfirmar la conexion...");/* while (blt_is_connected ()==FALSE && timeout<100) { delay (2); timeout+=20; idle (); }*/ printf ("\fRecibiendo...\n\nEspere por\nfavor"); while (finCarga==0) { letraRecibida=recibirCharBT ();
if (letraRecibida!=-1) printf ("%c", letraRecibida); if (letraRecibida=='!') { finCarga=1; } idle (); } letraRecibida=recibirCharBT (); while (letraRecibida!='?') { if (letraRecibida!=-1) { letr [0]=(char)letraRecibida; letr [1]='\0'; while (letraRecibida!='|') {//obtiene el codNom strcat (codNom, letr); letraRecibida=recibirCharBT (); letr [0]=(char)letraRecibida; letr [1]='\0'; } strcpy (Cliente, codNom);//pone en cliente su codigo strcat (Cliente, "|\0"); letraRecibida=recibirCharBT (); letr [0]=(char)letraRecibida; letr [1]='\0';
while (letraRecibida!='|') {//completa al info del cliente strcat (Cliente, letr); letraRecibida=recibirCharBT (); letr [0]=(char)letraRecibida; letr [1]='\0'; printf ("%c", letraRecibida); } printf ("\fC:%s.", Cliente); WaitForKey (); abrirDBRuta (); agregarRegistroClienteTexto (Cliente); //FALTA: GRABAR EL CLIENTE************************************************************************************* cerrarDBRuta ();
totalRuta++; letraRecibida=recibirCharBT (); letr [0]=(char)letraRecibida; letr [1]='\0'; while (letraRecibida!='!') { finCarga=0;//representara un contador de el num de pipes strcpy (Pedido, codNom); strcat (Pedido, "|\0"); while (finCarga<2) { strcat (Pedido, letr); letraRecibida=recibirCharBT (); letr [0]=(char)letraRecibida; letr [1]='\0'; if (letraRecibida=='|')finCarga++; } abrirDBPedido (); agregarRegistroPedidoTexto (Pedido); //FALTA: GRABAR EL PEDIDO********************************************************************************** cerrarDBPedido ();
//printf ("\nP:%s.", Pedido); //WaitForKey (); letraRecibida=recibirCharBT (); letr [0]=(char)letraRecibida; letr [1]='\0'; }
letraRecibida=recibirCharBT (); letr [0]=(char)letraRecibida; letr [1]='\0'; } //letraRecibida=recibirCharBT (); free (Cliente); free (Pedido); free (codNom); Cliente=(char*)malloc (29*sizeof (char)); memset( Cliente, '\0', sizeof( Cliente )); codNom=(char*)malloc (8*sizeof (char)); memset( codNom, '\0', sizeof( codNom )); Pedido=(char*)malloc (20*sizeof (char)); memset( codNom, '\0', sizeof( Pedido )); } free (Cliente); free (Pedido); free (codNom); cerrarServidor (); printf ("\nretornando %d", totalRuta); return totalRuta;
}
|
pero me dio lo mismo, ahora si use punteros y todo pero es la misma cosa, es decir puedo grabar los clientes pero no los pedidos. |
| | Volver arriba | |  | | |
| No puede crear mensajes No puede responder temas No puede editar sus mensajes No puede borrar sus mensajes No puede votar en encuestas
|
|
| |