/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

AYuda con algoritmo y memoria

 
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
GoldOozaru



Registrado: 21 Jun 2007
Mensajes: 55

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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
      Índice del Foro elrincondelc.com -> Principiantes C/C++
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com