0

メンバー変数として 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が行うパディングのせいだと思います

4

0 に答える 0