2012-03-19 27 views
5

To jest klasa hierarchia, która używa mój program:Tajemniczy przepełnienie stosu w konstruktorze

enter image description here

Konstruktor TForm_Upgrade_Database wygląda jak następuje:

__fastcall TForm_Upgrade_Database :: TForm_Upgrade_Database (TComponent * Właściciel, int latest_version) : TForm (właściciel) { }

Po starając się stworzyć instancję FORMULAR

TForm_Upgrade_Database *dlg = new TForm_Upgrade_Database(this, newest_version); 

mój program wyrzuca EStackOverflow wyjątkiem

enter image description here

zatrzymałem program i prowadził ją ponownie z przerwania w konstruktorze TForm_Upgrade_Database. Po kilku kroków callstack wygląda następująco:

enter image description here

Jak to jest, że konstruktor TCustomForm utrzymuje próby wywołania konstruktora swojego potomka ???

minimalna sprawdzian:

so_project.cpp:

//--------------------------------------------------------------------------- 

#include <vcl.h> 
#pragma hdrstop 

#include "f_form.h" 
//--------------------------------------------------------------------------- 
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 
{ 
    TForm_Upgrade_Database *form = new TForm_Upgrade_Database(NULL, 10); 
    delete form; 
    form = NULL; 

    return 0; 
} 
//--------------------------------------------------------------------------- 

f_form.cpp:

//--------------------------------------------------------------------------- 

#include <vcl.h> 
#pragma hdrstop 

#include "f_form.h" 
//--------------------------------------------------------------------------- 
#pragma package(smart_init) 
#pragma resource "*.dfm" 
TForm_Upgrade_Database *Form1; 
//--------------------------------------------------------------------------- 
__fastcall TForm_Upgrade_Database::TForm_Upgrade_Database(TComponent* Owner, int x) 
    : TForm(Owner) 
{ 
} 
//--------------------------------------------------------------------------- 

f_form.h:

//--------------------------------------------------------------------------- 

#ifndef f_formH 
#define f_formH 
//--------------------------------------------------------------------------- 
#include <Classes.hpp> 
#include <Controls.hpp> 
#include <StdCtrls.hpp> 
#include <Forms.hpp> 
//--------------------------------------------------------------------------- 
class TForm_Upgrade_Database : public TForm 
{ 
__published: // IDE-managed Components 
private: // User declarations 
public:  // User declarations 
    __fastcall TForm_Upgrade_Database(TComponent* Owner, int x); 
}; 
//--------------------------------------------------------------------------- 
extern PACKAGE TForm_Upgrade_Database *Form1; 
//--------------------------------------------------------------------------- 
#endif 
+2

Zrzuty ekranu i diagramy naprawdę nie pomagają nikomu zidentyfikować problemu. Proszę skonstruować [** minimal ** przypadek testowy] (http://sscce.org), a następnie opublikować kod. –

+0

Czy tworzysz kolejny obiekt aktualizacji w konstruktorze? – perreal

+0

Kolejny problem z przepełnieniem stosu w StackOverflow :) – nikhil

Odpowiedz

4

TForm ma wirtualną konstruktor które ma TComponent* i int parametrów w to zamówienie. Nadpisujesz ten konstruktor. Wywołanie konstruktora klasy podstawowej, który przyjmuje tylko parametr TComponent*, polega na tworzeniu pętli rekursywnej, gdy konstruktorzy nawiążą do siebie połączenia wewnętrzne.

Rozwiązaniem jest to, co powiedział prawdy. Musisz zmienić parametry swojego konstruktora pochodnego, aby nie przesłonić już konstruktora klasy podstawowej TComponent*/int. Wystarczy zmienić kolejność parametrów lub zmienić int na inny typ danych.

+0

Dobry połów. Nigdy nie uderzyłem w ten problem, ale to więcej szczęścia niż osądu ... – Roddy

+0

Ciekawe, nie zauważyłem tego. Właśnie próbowałem każdego sposobu, aby go uruchomić. – truthseeker

1

Myślę, że ma to związek z nietypowymi rozwiązaniami w bibliotece delphi. Biblioteki VCL są napisane i skompilowane w Delphi Pascal. Współpraca z C++ odbywa się poprzez pliki interfejsu (z rozszerzeniem * .hpp). Skompilowany kod binarny prawdopodobnie wyszukuje parametry konstruktora na niewłaściwych przesunięciach pamięci. Jest to prawdopodobnie problem z wywołaniem konwencji.

Udało mi się utworzyć instancję formularną przy zmianie parametrów w konstruktorze, aby nowy parametr był pierwszy.

f_form.h:

__fastcall TForm_Upgrade_Database(int x, TComponent* Owner); 

f_form.cpp:

__fastcall TForm_Upgrade_Database::TForm_Upgrade_Database(int x, TComponent* Owner) 
    : TForm(Owner) 
{ 
} 

so_project.cpp:

TForm_Upgrade_Database *form = new TForm_Upgrade_Database(10, NULL); 
Powiązane problemy