为什么 fstream put 函数在我的驱动器上填充了 4GB 的 space?
Why is fstream put function filling 4GB of space on my drive?
无论出于何种原因,我的程序在我的驱动器上占用了 4GB 的 space。为什么?
我使用断点将其缩小到这个 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;
}
}
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;
}
}
有人知道为什么会这样吗?
根据 /J (Default char Type Is unsigned),默认情况下 char
在 Visual C++ 中签名。所以在 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 字节的块;这真的是您想要的吗?)
无论出于何种原因,我的程序在我的驱动器上占用了 4GB 的 space。为什么?
我使用断点将其缩小到这个 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;
}
}
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;
}
}
有人知道为什么会这样吗?
根据 /J (Default char Type Is unsigned),默认情况下 char
在 Visual C++ 中签名。所以在 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 字节的块;这真的是您想要的吗?)