我有一个带有 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 所做的一些填充