C++BuilderでDelphiのレコード型を使用したときに発生するaccess violationと回避方法

概要

C++BuilderでDelphiのレコード型を大量に生成するとaccess violationエラーが発生します。

accessviolation01

再現方法

Delphiでレコード型を作成します。
ここでは、メンバ変数に文字列型Fを持つTFoo型を作成しました。

unit Unit2;

interface

type
  TFoo = record
  public
    F: string;
    constructor Create(const AF: string);
  end;

implementation

constructor TFoo.Create(const AF: string);
begin
  Self.F := AF;
end;

end.

C++Builderで、TFoo型を使用します。

#include "Unit2.hpp"

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  TFoo("01");
  TFoo("02");
  TFoo("03");
  TFoo("04");
  TFoo("05");
  TFoo("06");
  TFoo("07");
  TFoo("08");
  TFoo("09");
  TFoo("10");
}

accessviolation01

accessviolation02

ターゲットプラットフォームを「32bit Windows」にしてこのコードを実行すると、「TFoo(“07”);」でaccess violationエラーが発生します。
(エラーの発生位置はコードによって異なり、常に7件目とは限りません。)

ターゲットプラットフォームを「64bit Windows」のときはエラーは発生しません。

回避策(1) 変数名をつける

変数名をつけると、エラーは発生しないようです。

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  TFoo foo01("01");
  TFoo foo02("02");
  TFoo foo03("03");
  TFoo foo04("04");
  TFoo foo05("05");
  TFoo foo06("06");
  TFoo foo07("07");
  TFoo foo08("08");
  TFoo foo09("09");
}

回避策(2) 生成用関数を用意する

他の関数で生成すると、エラーは発生しないようです。

TFoo CreateFoo(UnicodeString F)
{
  return TFoo(F);
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
  CreateFoo("01");
  CreateFoo("02");
  CreateFoo("03");
  CreateFoo("04");
  CreateFoo("05");
  CreateFoo("06");
  CreateFoo("07");
  CreateFoo("08");
  CreateFoo("09");
  CreateFoo("10");
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください