最近,我试图解决一个问题,这让我有点困扰。
问题是,当我调用一个方法并传递一个结构,它有一个数组指针作为成员时,前面两个字节在返回方法后被清零。即使它们被初始化为(在这种情况下)0xFF。他们总是没有被玷污。有时发生了,他们确实带来了一些价值,但我无法找到任何模式。
我最近解决了这个问题。我不得不传递Bitmap结构的指针。但是我不明白为什么,当我只需要更改数组的值时,正如你在下面看到的那样,我正在写入相同的地址,但是当它从方法返回时,2个第一个字节为零;
有人可以解释我错过了什么吗?感谢。
我有这段代码:
void Printer::offsetBitmapVertically(Bitmap bitmap, uint8_t offset)
{
byte length = bitmap.arrayLength();
byte previousValue = 0;
for (byte i = 0; i < bitmap.width; i++)
{
byte previousValue = 0;
for (byte j = 0; j <= bitmap.height / 8; j++)
{
byte index = i + bitmap.width * j;
byte tmp = bitmap.value[index] >> 8 - offset;
bitmap.value[index] = (bitmap.value[index] << offset) | previousValue;
Serial.print("address: "); Serial.println((uint16_t)&bitmap.value[index]);
Serial.print("value: "); Serial.println(bitmap.value[index], HEX);
previousValue = tmp;
}
}
Serial.println("");
Serial.println("");
Serial.println("");
}
void TextPrinter::print(const char *str, Point p, Font* p_font)
{
while (*str)
{
Bitmap bitmap = p_font->getBitmapFromCharacter(*str);
offsetBitmapVertically(bitmap, 0);
for (int i = 0; i < bitmap.arrayLength(); i++)
{
Serial.print("address: "); Serial.println((uint16_t)&bitmap.value[i]);
Serial.print("value: "); Serial.println(bitmap.value[i], HEX);
}
p_lcd->writeBitmap(bitmap.value, p.x, p.y, bitmap.width, bitmap.height);
p.x += bitmap.width + 2;
str++;
}
}
/*
address: 1240
value: FF
...
address: 1241
value: FF
...
address: 1240
value: 0
address: 1241
value: 0
...
*/
Bitmap结构定义如下
struct Bitmap
{
public:
Bitmap(const byte* bitmapArray);
~Bitmap() { delete [] value; }
uint8_t arrayLength() { return arrayLength(width, height); }
static uint8_t arrayLength(uint8_t width, uint8_t height) { return width * ((height / 8) + 1); } // TODO potencional bug when height % 8 == 0
byte* value;
uint8_t width;
uint8_t height;
};
Bitmap::Bitmap(const byte* bitmapArray)
{
width = pgm_read_word(bitmapArray);
height = pgm_read_word(bitmapArray + 1);
byte length = arrayLength(width, height);
value = new byte[length];
for (byte i = 0; i < length; i++)
value[i] = pgm_read_word(bitmapArray + i + 2); // first two bytes were width and height
}
答案 0 :(得分:2)
您按值传递bitmap
变量。这意味着offsetBitmapVertically
函数从print
函数接收变量的副本。
更改副本当然不会改变原件。
您应该通过引用传递参数:
void Printer::offsetBitmapVertically(Bitmap& bitmap, uint8_t offset) { ... }
// ^
// Note ampersand here
另请注意,除非您更改为通过引用传递,否则您的代码会导致未定义的行为。这是因为默认的复制构造函数(将用于创建副本)只是复制指针,导致两个不同的对象具有指向同一内存的相同指针。一旦bitmap
函数内的offsetBitmapVertically
变量超出范围并被破坏,它将delete[]
该内存,这意味着原始指针不再指向已分配的内存。
了解the rules of three, five and zero以了解如何解决此问题。