You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何BlockRead/BlockWrite可使用远小于数据量的缓冲区且无报错?

为何1字节变量能容纳48字节数据且无溢出报错?

问题代码

program OverflowTest;
var
    src: file;
    dest: file;
    res: longint;
    buf: byte;
begin
    assign(src, '48_bytes_file.txt');
    assign(dest, 'copy_of_48_bytes_file.txt');
    reset(src, 2);
    rewrite(dest, 2);
    BlockRead(src, buf, 24, res);   
    BlockWrite(dest, buf, 24, res);
    close(src);
    close(dest);
end.

问题描述

我编写了如上程序,尝试将48字节的数据读取到仅能容纳1字节的byte类型变量buf中,程序却能正常运行,数据无丢失地复制到目标文件。为何可向1字节变量写入48字节数据,且未出现内存溢出、缓冲区大小无效等报错?

原因解析

  • 文件记录大小的影响:你在调用reset(src, 2)和rewrite(dest, 2)时,指定了文件的记录大小为2字节。BlockRead和BlockWrite的第三个参数是记录数量,不是字节数。所以BlockRead(src, buf, 24, res)实际是读取24个记录,总字节数为24*2=48字节,刚好匹配源文件的大小。
  • Pascal的内存操作特性:BlockRead/BlockWrite并不检查传入缓冲区的实际容量,它只接收一个内存起始地址(这里是buf变量的内存地址),然后从该地址开始连续写入/读取指定数量的记录。由于buf是byte类型仅占1字节,这一操作本质是内存越界写入——数据会覆盖buf之后的栈内存空间。
  • 程序正常运行只是巧合:你的程序没崩溃或报错,只是因为越界覆盖的内存区域刚好没有破坏程序的关键数据(比如栈帧返回地址、其他核心变量)。这种行为属于未定义行为,完全依赖编译器的内存布局和运行环境,换编译器、调整变量顺序或添加其他变量后,程序极可能崩溃、出现数据错乱,甚至引发安全问题。
  • 正确的做法:应该定义足够容量的缓冲区,比如buf: array[1..48] of byte;,或者使用动态数组,确保缓冲区能容纳所有要读取的数据。

内容的提问来源于stack exchange,提问作者Nikita Burak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 13:49:58