Linux上でC++を使用しているときに問題が発生しました。Linuxでのstd :: mapによるメモリアライメントの問題
私はこのようになりますベースメッセージクラスを持っている:ここでは
class Der1 : public MsgBase
{
public:
Der1();
virtual ~Der1();
// IEs
MSGIE_UINT32 ueId;
MSGIE_String configFileName;
};
MSGIE_UINT32とMSGIE_StringしたがってMSGIEBaseから派生したクラスです:Der1はMsgBaseから派生してのように見えるさ
class MsgBase
{
public:
MsgBase(unsigned int msgid);
map < unsigned int, MSGIEBase* > messageIE_Map; // map for IEs
unsigned int messageId; // 32 bit message id
};
クラスそれらのアドレスは上記の基底クラスで定義されたマップに格納することができます。 Der1が構築されると、ueIdとconfigFileNameのアドレスがマップに格納されます。 マップのサイズを印刷すると(gdbとプログラムで)、24となります。 [_M_header = 16、_M_node_count = 4、_M_key_compare = 1,3バイトのパディングです。
ここまではすべて問題ありません。 Der1オブジェクトポインタはイベントオブジェクトの中に入れられ、イベントはキューにポストされます。イベントクラスは次のようになります。
class Event
{
public:
MsgBase* msgPtr;
};
異なるスレッドは、キューからイベントを削除するmsgPtrを抽出し、Der1ポインタにキャストして、問題が始まる場所です。
ここでプログラムのマップのサイズを印刷すると21になります。つまり、MsgBaseクラスの次のメンバーのアドレス、つまりmessageIdが3バイトずれるため、messageIdの値が完全に変更されます。 (gdbを通して見ると、アドレスはそのままで、マップのサイズも24です)。
これは私の知る限りでは、メモリアラインメントが異なる機能で一貫していないため、なぜクラスのメモリのアドレスが新しいクラスを使用して割り当てられたのか。私はLinux 2.6.27を使用しています。 、gccバージョン4.1.1 、RHEL-4。非仮想デストラクタ/コピー/割り当ての問題を除外するための
これらのオブジェクトをどのように操作するかによって異なります。コードを表示する。 (私はメモリアライメントの問題だとは思わない) – BatchyX
マップの大きさとメモリのアライメントについてのあなたの前提は、間違ったパスを取っていると思う。あなたは実際の問題を説明することは決してありません。私は関係のないと思う症状だけを説明します。あなたのキューからポップしたときに、あなたのプログラムで(間違って)どうなるでしょうか?私は、この時点でソースのプッシュとポップの部分がはるかに関連性があると思うだろう、私はそこに問題があると推測している。 – Joe
実際に問題がありますか?関連するコードのいくつかを教えてください。 –