无论出于何种原因,我的程序占用了我的驱动器上 4GB 的空间。为什么?
我使用断点将其范围缩小到这个for循环:
int blockPos = 1;
char blockAddressPos = 0x00;
for (int d = 0; d < img.width * img.height * img.channels; d++) {
tf.write(blockPos, blockAddressPos, (char)img.data[d]);
//printf("Byte write: %i\n", (unsigned int)img.data[d]);
blockAddressPos++;
break; // Debug purposes
if (blockAddressPos >= 0xFF) {
blockPos++;
blockAddressPos = 0x00;
}
}
Run Code Online (Sandbox Code Playgroud)
功能tf.write():
void TableFormatter::write(int block, char blockAddr, char data) {
if (_valid) {
if (block == 0) {
if (blockAddr <= 0x0F) {
// Core file metadata is located here, disallow write access or shift address to 0x10
blockAddr = 0x10;
_states.write.TableMetadataWarning = true;
}
}
unsigned int location = (block << 8) | blockAddr;
_table.seekp(location, FileBeginning);
_table.put(data);
} else {
_states.fileSignatureInvalid = true;
}
}
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么会发生这种情况?
根据/J (Default char Type Is unsigned),在 Visual C++ 中默认char是有符号的。因此,在blockAddressPos超过后0x7F,它会回绕并且很可能变为负值,例如0x80 = -128。
当您将此负值传递给 时tf.write(),该行将unsigned int location = (block << 8) | blockAddr;提升blockAddr为int,并进行符号扩展。因此,您执行相当于 的操作location = (block << 8) | 0xFFFFFF80,这就是您的 ~4 GB 的来源。
您可能希望将blockAddressPos参数更改blockAddr为unsigned char或更好uint8_t。
(顺便说一句,修复后,您的测试blockAddressPos >= 0xFF将写入大小为 255 字节的块,而不是 256;这真的是您想要的吗?)