首次使用Valgrind检测程序遇getcwd(buf)不可寻址错误,求解决方案
Valgrind错误:getcwd参数指向不可访问字节的原因与修复
首次使用Valgrind测试程序时遇到如下错误,无法找到相关解决方法,求助问题原因及修复方案:
最小可复现代码
#include <sys/stat.h> #include <stdio.h> #include <stdlib.h> int main(){ char* dir = "testdir"; mkdir(dir,0777); char* buf = calloc(1, sizeof(char)*255); char* directory = realpath(dir, buf); printf("%s\n", directory); free(buf); }
Valgrind检测报告(中文翻译)
==18518== 系统调用参数getcwd(buf)指向不可访问的字节 ==18518== 位于 0x4969AF2: getcwd (getcwd.c:78) ==18518== 由 0x48AD520: realpath@@GLIBC_2.3 (canonicalize.c:88) 调用 ==18518== 由 0x109216: main (in /home/sol/Documents/SOLProject/.test/a.out) 调用 ==18518== 地址 0x4a5013f 是大小为255字节的分配块之后的0字节位置 ==18518== 位于 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so) ==18518== 由 0x1091FF: main (in /home/sol/Documents/SOLProject/.test/a.out) 调用 ==18518== /home/sol/Documents/SOLProject/.test/testdir ==18518== ==18518== 堆内存摘要: ==18518== 退出时使用中:0字节,0块 ==18518== 总堆内存使用:2次分配,2次释放,共分配1,279字节 ==18518== ==18518== 所有堆块均已释放——无内存泄漏可能 ==18518== ==18518== 如需查看检测到的错误和被抑制错误的列表,请使用-s参数重新运行 ==18518== 错误摘要:1个上下文产生1个错误(被抑制:0个,共0个)
问题原因
你手动分配的255字节缓冲区不足以容纳realpath生成的完整绝对路径(包括末尾的空终止符'\0')。realpath内部调用getcwd时,会尝试向缓冲区写入超出你分配的255字节范围的数据,导致Valgrind检测到越界访问。
修复方案
方案一:使用系统定义的最大路径长度分配缓冲区
引入<limits.h>头文件,使用PATH_MAX宏(系统定义的最大路径长度)分配足够大的缓冲区,确保能容纳任何合法路径:
#include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #include <limits.h> int main(){ char* dir = "testdir"; mkdir(dir,0777); char* buf = calloc(1, PATH_MAX); char* directory = realpath(dir, buf); printf("%s\n", directory); free(buf); return 0; }
方案二:让realpath自动分配内存
将realpath的第二个参数设为NULL,此时函数会自动调用malloc分配足够的内存来存储路径,之后只需释放返回的指针即可。这种方法更安全,无需手动估算缓冲区大小:
#include <sys/stat.h> #include <stdio.h> #include <stdlib.h> int main(){ char* dir = "testdir"; mkdir(dir,0777); char* directory = realpath(dir, NULL); if (directory != NULL) { printf("%s\n", directory); free(directory); } return 0; }
注意事项
- 使用
PATH_MAX时,需确认目标系统支持该宏(多数类Unix系统都支持); - 第二种方案中务必检查
realpath的返回值,若路径无效(比如目录不存在),函数会返回NULL,直接访问会导致段错误; - 调用
mkdir时可以添加错误检查,避免目录已存在时的错误干扰。
内容的提问来源于stack exchange,提问作者DravStart
相关产品推荐
相关产品推荐

