为什么 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 的来源。

您可能想将 blockAddressPosblockAddr 参数更改为 unsigned char,或者更好的是 uint8_t.

(顺便说一句,在这个固定的情况下,您的测试 blockAddressPos >= 0xFF 将写入大小为 255 字节而不是 256 字节的块;这真的是您想要的吗?)