| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
rockman2003 Master

Registrado: 27 Ene 2004Mensajes: 202Ubicación: Madrid
|
Publicado: Mar 08 Sep, 2009 3:53 pm Asunto: Error extraño Codeguard |
|
|
Hola foro:
Me encuentro con un error que me devuelve el Codeguard muy extraño.
El error es el siguiente:
Attempt to access 224 byte(s) at 0x000.... The this pointer points to heap block 0x000... which is only 220 bytes long.
Además tengo otro error exactamente igual que este pero en vez de 224 bytes son 608, y 604 en vez de 220.
La linea de codigo pertence a la libreria AdoDB.h
| Código: | inline void __fastcall Open(void){ TCustomConnection::Open(); |
Esta linea de la libreria AdoDB.h la llamo yo a partir de la siguiente instruccion:
| Código: | r_datos = new TADODataSet(NULL); |
Ayudarme por favor.
He estado mirando en internet y solo he encontrado ayuda en chino y ruso, y me es muy complicado entenderlo, he visto que puede ser algo de un parche del Ado, pero no me hagais mucho caso.
Actualmente estoy trabajando con C++Builder 6.0
Muchas gracias |
|
| Volver arriba |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Mar 08 Sep, 2009 7:02 pm Asunto: |
|
|
Según Embarcadero, este error se corrigió en el C++Builder 2006:
http://qc.embarcadero.com/wc/qcmain.aspx?d=3029
Y como ves en el enlace de arriba dan una solución, que es añadir un par de líneas en el archivo "???\cbuilder6\include\vcl\ADODB.hpp". Que serian:
- Añadir: #pragma pack(push, 4) alrededor de la línea 142, antes de la declaración de la clase TADOConnection:
class PASCALIMPLEMENTATION TADOConnection : public Db::TCustomConnection
- Y despues de la declaración de la clase, despues del "};" (alrededor de la línea 287): #pragma pack(pop)
Sería bueno también antes de hacer estas modificaciones tener la última actualización del BCB6 y que incluía todas las anteriores:
https://cppbuilder.es/viewtopic.php?p=38539#38539 |
|
| Volver arriba |
|
 |
rockman2003 Master

Registrado: 27 Ene 2004Mensajes: 202Ubicación: Madrid
|
Publicado: Mar 08 Sep, 2009 9:38 pm Asunto: |
|
|
Muchas gracias por la respuesta _Leo.
El error de 224 bytes se ha quitado pero continua el de 608 bytes.
Un saludo, y de nuevo muchas gracias. |
|
| Volver arriba |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Mar 08 Sep, 2009 10:04 pm Asunto: |
|
|
| rockman2003 escribió: | | El error de 224 bytes se ha quitado pero continua el de 608 bytes. |
Se trata de lo mismo, pero esta vez con la clase TADODataSet. Busca en la misma cabecera la declaración (class PASCALIMPLEMENTATION TADODataSet : public TCustomADODataSet) y haz lo mismo con los "pragmas" al principio y al final.
El consejo que suelen dar en los foros de Embarcadero es que ignores estos avisos mientras no causen algún error que impida ejecutar tu programa, ya que si no CodeGuard acabara encontrándote muchas cosillas en el código de Embarcadero. Y usar principalmente CodeGuard para buscar errores en tu propio código. |
|
| Volver arriba |
|
 |
rockman2003 Master

Registrado: 27 Ene 2004Mensajes: 202Ubicación: Madrid
|
Publicado: Jue 10 Sep, 2009 12:29 am Asunto: |
|
|
Muchas gracias _Leo.
La razón de porque quiero quitar estos mensajes es porque quiero ejecutar el programa con el CodeGuard activado ya que tengo en mi código numerosos errores Access Violation al cerrar los formulario de mi aplicacion y no encuentro la razón.
Lo comentaba en otro hilo... yo creo los formulario de la manera
| Código: | if (!Formulario)
Formulario = new TFormulario(this);
Formulario->Show(); |
Y los destruyo en el evento Close del formulario con...
| Código: | Action=caFree;
Formulario=NULL; |
|
|
| Volver arriba |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Jue 10 Sep, 2009 1:04 am Asunto: |
|
|
| rockman2003 escribió: | | Lo comentaba en otro hilo... yo creo los formulario de la manera |
Pues sin ver mas.. no creo que el problema este en esto.
Por si te puede servir de ayuda para localizar el problema:
- En las opciones de tu proyecto, en la pestaña "Linker" marca las opciones "Create debug information" y "Use debug libraries" (esta última es la realmente importante). Ahora haz un "rebuild" de tu proyecto y ejecútalo desde el IDE.
(Para que funcione es importante tener desmarcado "Build with runtime packages" en la pestaña "Packages" de las opciones del proyecto)
- Cuando salga la excepción: "Access violation at adress 00401ACA in..." fíjate en ese número que sale al lado y cópialo. Luego dale a OK. (Ahora puede que ya te este señalando donde está el error, si no es así sigue leyendo)
- A continuación vete al menú y abre la ventana CPU: "View -> Debug Windows -> CPU" y una vez en ella pulsa la combinación de teclas: CTRL+G e introduce el numero que habías apuntado anteponiéndole "0x", o sea 0x401ACA. En esa ventana puedes ver alrededor de donde ha ocurrido el error.
Hay casos en los que esto no funciona.. pero por intentarlo.. |
|
| Volver arriba |
|
 |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Jue 08 Oct, 2009 3:14 pm Asunto: |
|
|
Aunado a ello Revisa si despues del cierre de tus formularios, no estas usando alguna referencia a elementos que lo conforman. un ejemplo donde siempre te sale una "Access Violation..." es algo como esto.
Acces Violation 1
| Código: | // creacion del formulario
TForm *pTuForm = new TForm(this)
pTuForm->Show();
// si dentro del Form -- pTuForm que has creado lo destruyes
// y posteriormente intentas usar una variable o dato
// este va a marcarte un "Access Violation..."
void __fastcal TForm::botonClick(TObject Sender)
{
Action = caFree; // aqui estas liberando el formulario
Formulario=NULL; // Aqui ya no existe, Aqui Marca "Access Violation..."
} |
Access Violation 2
| Código: |
TForm *pTuForm = new TForm(this)
pTuForm->ShowModal();
delete pTuForm; // borras el formulario
pTuForm->Edit1->Text = "hola"; // Marca "Access Violation..."
Form2->Caption = pTuForm->Edit1->Text; // Marca "Access Violation..." |
Pues estas usando información que ya no existe, revisa tambien usando [F8] antes del cierre de tus formularios, para determinar que no estas haciendo referencias a datos de formularios que ya no "existen"
Saludos. _________________
 |
|
| Volver arriba |
|
 |
rockman2003 Master

Registrado: 27 Ene 2004Mensajes: 202Ubicación: Madrid
|
Publicado: Jue 08 Oct, 2009 3:22 pm Asunto: |
|
|
Hola Cesar, este es mi caso!!!
| César C. Salazar González escribió: | Aunado a ello Revisa si despues del cierre de tus formularios, no estas usando alguna referencia a elementos que lo conforman. un ejemplo donde siempre te sale una "Access Violation..." es algo como esto.
Acces Violation 1
| Código: | // creacion del formulario
TForm *pTuForm = new TForm(this)
pTuForm->Show();
// si dentro del Form -- pTuForm que has creado lo destruyes
// y posteriormente intentas usar una variable o dato
// este va a marcarte un "Access Violation..."
void __fastcal TForm::botonClick(TObject Sender)
{
Action = caFree; // aqui estas liberando el formulario
Formulario=NULL; // Aqui ya no existe, Aqui Marca "Access Violation..."
} |
|
Pero... si esto no puedo hacer... ¿donde pongo el puntero a NULL?, o dicho de otro modo... ¿como puedo saber que el formulario no esta creado? |
|
| Volver arriba |
|
 |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Jue 08 Oct, 2009 3:36 pm Asunto: |
|
|
En las opciones del proyecto (Proyect - Options - Forms)
Traspasa tus formularios a la parte de "Available Forms", Esto determina que los formularios no estan creados y puedes usar la forma, para generarlos.
| Código: |
if (!Formulario)
Formulario = new TFormulario(this);
Formulario->Show(); |
Posteriormente al "cerrar" tu formulario usa una llamada a Close() en lugar del Action = caFree;
| Código: | void __fastcal TForm::botonClick(TObject Sender)
{
this->Close(); // aqui estas liberando el formulario
} |
y si los estas habriendo con ShowModal();
| Código: |
if (!Formulario)
Formulario = new TFormulario(this);
Formulario->ShowMoadl();
delete Formulario;
Formulario = 0; // igual a cero
} |
_________________
 |
|
| Volver arriba |
|
 |
rockman2003 Master

Registrado: 27 Ene 2004Mensajes: 202Ubicación: Madrid
|
Publicado: Jue 08 Oct, 2009 3:54 pm Asunto: |
|
|
Gracias Cesar,
pero al hacer Close(), ¿donde pongo Formulario = 0 cuando no abro con ShowModal()?
Lo digo porque cuando vuelva a hacer if (!Formulario), no va a entrar por ahí y cascará ¿no? |
|
| Volver arriba |
|
 |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Jue 08 Oct, 2009 4:48 pm Asunto: |
|
|
Aunque aún no logro enteder imágino que estas usando formularios MDI
si es asi, yo uso la siguiente manera de abrirlos, indicando que estan dentro del programa principal que los carga.
usando el Método "Action = caFree" para liberarlos de la memoria cuando son MDI (claro esta que esto va dentro del botón, tal y como tu lo tienes en los anteriores post, y sin la asignación de NULL)
Nota: Esto va dentro del botón u opción cuando llamas al formulario a mostrar.
| Código: | //Formulario a llamar desde el form principal
int hija=0;
bool existe=false;
while(hija<this->MDIChildCount)
{
Application->ProcessMessages();
if(this->MDIChildren[hija]->Name=="Form_Mi_Formulario")
{
this->MDIChildren[hija]->BringToFront();
existe=true;
break;
}
hija++;
}
if(!existe)
{
TForm_TuModulo *pNC= new TForm_TuModulo(this);
pNC->Name = "Form_Mi_Formulario";
pNC->Show();
} |
En forma de ver, si el formulario existe y esta presente, entonces unicamente lo traigo al frente, si no es asi, entonces lo creo. _________________
 |
|
| Volver arriba |
|
 |
rockman2003 Master

Registrado: 27 Ene 2004Mensajes: 202Ubicación: Madrid
|
Publicado: Jue 08 Oct, 2009 5:06 pm Asunto: |
|
|
Es verdad, me estoy explicando fatal,
Vamos por partes
Esta es una aplicación con una gran cantidad de formularios, y no se tratar de MDI's. Debido a esto no quiero tener todos los formulario cargados en memoria, por lo que los tengo todos en Available Forms.
Desde mi formulario principal abro dichos formularios, dependiendo de la opción del usuario.
.... y aqui empieza el problema.
Yo antes los abria con ShowModal, por lo que en cada opción de menu ponía
| Código: |
TForm *Form = new TForm(this);
Form->ShowModal();
delete Form;
|
El problema es que los forumlarios modales hacen que la aplicación sea poco flexible por lo que quiero cambiarlo para que se abran normales.
La forma que tengo que abrirlos es mediante:
| Código: |
if (!Form)
Form = new TForm(this);
f->Show();
|
Mi problema es el liberar dicho formulario cuando lo cierro.
Si yo hago un Close(), o un caFree, pero no pongo
La siguiente vez que abra dicho formulario Form no valdrá NULL por lo que no hará new y cascará la aplicación.
La forma que yo tengo solucionado esto es, en el evento Close
| Código: |
Action = caFree;
Form = NULL;
|
Pero como tu bien dices no puedo poner Form a NULL cuando ya he liberado el formulario.
Espero haberme explicado mejor.[/code] |
|
| Volver arriba |
|
 |
Cesar C. Salazar Gonzalez Master


Registrado: 01 Oct 2002Mensajes: 2155Ubicación: San Cristóbal de Las Casas, Chiapas
|
Publicado: Jue 08 Oct, 2009 5:18 pm Asunto: |
|
|
Creo entonces que la cosa es mas fácil de lo que se intenta complicar.
1.- A tu formulario Principal establece la propiedad FormStyle a fsMDIForm
2.- A los formularios que vas a usar como ventanas de tu Aplicacion establece la propiedad FormStyle a fsMDIChild y llamalos desde la forma que esta en el post anterior, (un boton, o una opcion de Menu)
| Código: | //Formulario a llamar desde el form principal
int hija=0;
bool existe=false;
while(hija<this->MDIChildCount)
{
Application->ProcessMessages();
if(this->MDIChildren[hija]->Name=="Form_Mi_Formulario")
{
this->MDIChildren[hija]->BringToFront();
existe=true;
break;
}
hija++;
}
if(!existe)
{
TForm_TuModulo *pNC= new TForm_TuModulo(this);
pNC->Name = "Form_Mi_Formulario";
pNC->Show();
} |
3.- Cuando termines de usar los formularios creados por el paso No. 2, usa el Action = caFree; como siempre lo has manejado, pero sin la asignacion de NULL
| Código: | void __fastcal TForm::botonClick(TObject Sender)
{
Action = caFree; // aqui estas liberando el formulario
} |
y recuerda tener los formularios tipo MDI's en la parte de Availables Forms
Esperemos que ahora si funcione correctamente tu aplicación.
Nota: el usar los formularios MDI en mucho de los casos te ayuda a liberar la memoria correctamente. _________________
 |
|
| Volver arriba |
|
 |
|