Invalid write 通常对应越界写或释放后写,主要因数组越界、use-after-free、写野地址导致;需用 -g -O0 编译以准确定位,size 4 多为 int/float 越界。

Invalid write 通常对应越界写或释放后写
Valgrind 报 Invalid write of size N,基本可以锁定是程序试图往“不该写”的内存地址写入了 N 字节。它不是编译错误,而是运行时被 Memcheck 拦下的非法操作。背后最常见三类情况:
• 数组或缓冲区越界(堆/栈上都可能)
• 对已 free 或 delete 的指针再次写入(use-after-free)
• 写入未分配的野地址(比如空指针解引用、未初始化指针)
看报错行号前先确认是否关了编译器优化
如果 Invalid write 指向的行号明显“不合理”(比如指向一个纯声明语句、或者和你写的逻辑完全对不上),大概率是编译器优化打乱了指令顺序。Memcheck 依赖调试信息定位源码,而 -O1 及以上级别会让行号映射失真。
• 必须用 gcc -g -O0 或 g++ -g -O0 重新编译
• -O2 下 Valgrind 甚至可能漏报或误报 Invalid write,尤其涉及未初始化值传播时
• 不要指望靠 --track-origins=yes 补救——它只对未初始化值有效,不解决行号错位
size 4 很可能是 int 或 float 写越界
Invalid write of size 4 是高频报错,因为 C/C++ 中 int、float、普通指针在 64 位系统上常占 4 字节(取决于 ABI 和编译选项)。遇到这个 size,优先检查:
• int arr[10]; arr[10] = 1;(下标 0–9 合法,10 越界)
• malloc(40); 分配了 10 个 int,但循环写了 i = 0; i <br>• <code>strcpy / memcpy 目标缓冲区不够大,而源字符串长度超限
• 结构体成员偏移计算错误,导致写到相邻字段之外
Address is X bytes after a block alloc'd 是关键线索
报错里这句 Address 0x... is 0 bytes after a block of size N alloc'd 比 “Invalid write” 四个字更有价值:
• 0 bytes after:刚好踩在分配块末尾之后,典型数组越界(如 arr[n] 写第 n+1 个元素)
• 8 bytes after:可能跨了两个 int,或是结构体 padding 导致的错位
• 如果显示 Address 0x... is inside a block of size N free'd,那就是 use-after-free,得顺着 free 那行往上查谁还在用这个指针
• 注意:Valgrind 的地址是虚拟地址,不能直接拿去 gdb 里查,但结合源文件行号 + 变量名就能快速定位


















