メンバー変数として uint8_t の配列を持つクラスがあります。メンバー配列に書き込むと、他のクラスの静的メンバーが配列内の値で上書きされます。これらのオブジェクトを次のように使用しています。
SystemInit();
Reporting *r = Reporting::Instance();
r->reportCode(d, LIGHTS, 0xDEADBEEF);
SSD1305Params *ssdp = new SSD1305Params();
ssdp->clear(PIXEL_ON);
SSD1305 *disp = SSD1305::Instance();
r->reportCode(d, LIGHTS, (int)disp);
私の例では、次のように定義されたクラスがあります。
class SSD1305Params {
private:
static const int visible_buffers = 512; // Visible buffers
// (width * height) / pix_in_page
public:
uint8_t buffer[visible_buffers];
void clear(int);
};
その clear 関数は次のように実装されています。
void SSD1305Params::clear(int val) {
for (int i = 0; i < visible_buffers; i++) {
if (val == PIXEL_ON)
buffer[i] = 0xFF; // <<<< Value overwrites statics
else
buffer[i] = 0; // <<<< Value overwrites statics
}
}
シングルトンとして実装された別のクラスがあります。これは次のように実装されます。
SSD1305.h:
class SSD1305 {
private:
static SSD1305* instance;
protected:
SSD1305();
public:
static SSD1305 *Instance();
};
SSD1305.cpp:
SSD1305 *SSD1305::instance = 0;
SSD1305::SSD1305() {
}
SSD1305 *SSD1305::Instance() {
if (instance == 0) {
instance = new SSD1305();
}
return instance;
}
SSD1305Params で「クリア」を呼び出すたびに、バッファに書き込まれた値が SSD1305 の静的メンバー「インスタンス」を上書きします。そのため、'clear' を呼び出した後に SSD1305 のインスタンスを取得しようとすると、値が 0x00000000 または 0xFFFFFFFF のポインターが取得されます。そのため、SSD1305 オブジェクトで後続の関数を呼び出すと、SEGFAULT が発生します。これは、シングルトンとして実装したすべてのオブジェクト (レポート メカニズムを含む) に当てはまります。
なぜこれが起こっているのでしょうか?SSD1305Params をインスタンス化すると、バッファーには独自のスペースが定義されると思いますが、他のオブジェクトの静的メンバーと同じスペースを占有しているようです。ありがとう!
編集: ssdp の作成をコメントアウトして、SSD1305 インスタンスが配置されている場所を取得すると、アドレス 0x20000030 にあることがわかります。メモリ マップを見ると、data.impure_data というセクション内にあります。
.data.impure_data
0x20000004 0x60 c:/program files (x86)/atmel/atmel toolchain/arm gcc/native/4.8.1443/arm-gnu-toolchain/bin/../lib/gcc/arm-none-eabi/4.8.4/../../../../arm-none-eabi/lib/armv7-m\libc_s.a(lib_a-impure.o)
.data._impure_ptr
一体何が起こっているのですか?私はそれがヒープにあると思いましたか?うーん
編集2:
レポート メカニズムを使用して (clear を呼び出さずに) オブジェクトのアドレスを取得すると、次の値になります。
Reporting: 0x20000008
ShiftRegisters: 0x20000018 (singleton used inside Reporting)
SSD1305Params: 0x20000030
SSD1305Params->buffer: 0x20000040
SSD1305: 0x20000248
したがって、バッファが 512 バイトを超えて割り当てられていることがわかります。それは実際には520です。これは、mallocが行うパディングのせいだと思います