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

首次使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 05:04:52