在构造函数中的神秘堆栈溢出

时间:2012-03-19 15:21:57

标签: c++ constructor stack-overflow c++builder c++builder-6

这是我的程序使用的类层次结构:

enter image description here

TForm_Upgrade_Database的构造函数如下所示:

__ fastcall TForm_Upgrade_Database :: TForm_Upgrade_Database(TComponent * Owner,     int newest_version)         :TForm(所有者)     {     }

尝试创建公式

的实例后
TForm_Upgrade_Database *dlg = new TForm_Upgrade_Database(this, newest_version);

我的程序抛出EStackOverflow异常

enter image description here

我停止了程序,并在TForm_Upgrade_Database构造函数中使用断点再次运行它。几步后,callstack看起来像这样:

enter image description here

TCustomForm构造函数如何继续尝试调用其后代的构造函数???

最小测试用例:

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 个答案:

答案 0 :(得分:4)

TForm有一个虚拟构造函数,按顺序获取TComponent*int个参数。你正在重写那个构造函数。通过调用只接受TComponent*参数的基类构造函数,实际上当这些构造函数在内部相互调用时,您创建了一个递归循环。

解决方案是真理主义者所说的。您必须更改派生构造函数的参数,以便不再覆盖基类TComponent*/int构造函数。更改参数的顺序就足够了,或者您可以将int更改为其他数据类型。

答案 1 :(得分:1)

我认为这与delphi库中的一些非标准解决方案有关。 VCL库是用Delphi Pascal编写和编译的。与C ++的合作是通过接口文件(扩展名为* .hpp)进行的。编译的二进制代码可能在不正确的内存偏移上搜索构造函数参数。所以这可能是调用约定的问题。

我在构造函数中更改参数时成功创建了formular实例,以便新参数是第一个。

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);