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

C实现_unsetenv编辑.bashrc删环境变量时末行多出重复文本

问题根因

末尾重复追加最后一行片段的问题是3个代码bug叠加导致的,没有特殊逻辑错误:

  • 文件未截断残留旧内容:你用r+模式打开文件后从起始位置写入新内容,但删除一行后新内容总长度比原文件短,写完后没有截断文件,原文件末尾多出来的旧内容没有被清理,刚好就是你看到的重复的SOME='CHANGED'片段。
  • temp_split内存分配大小错误:你写的temp_split = malloc(sizeof(char) * lines - 1)是按1字节的char类型分配空间,但temp_split是char**类型的指针数组,64位系统下每个指针占8字节,实际分配空间远小于需求,造成内存越界写入,属于未定义行为。
  • 隐藏野指针bug:string_count函数中将栈上局部变量words的地址存入返回值,函数退出后该地址指向的栈内存会被回收,成为野指针,当前场景没触发崩溃只是巧合。
修复方案

按以下顺序修改代码即可解决问题:

  1. 修正temp_split的内存分配
    将错误的分配代码替换为正确的指针数组分配:
    // 原错误代码:temp_split = malloc(sizeof(char) * lines - 1);
    temp_split = malloc(sizeof(char*) * (lines - 1));
    
  2. 写文件前重置指针,写完后截断文件
    打开文件、完成mmap后,先把文件指针重置到起始位置;所有内容写入完成后,先刷新IO缓冲区,再将文件截断到当前写入位置的长度,清除旧内容残留:
    stream = fopen(filename, "r+");
    if (!stream)
        return (-1);
    rewind(stream); // 新增:指针回到文件开头
    f_d = stream->_fileno;
    // ... 中间的mmap、split、循环写入逻辑不变 ...
    
    // 循环写入完成后新增以下逻辑
    fflush(stream);
    ftruncate(f_d, ftell(stream)); // 截断文件到实际写入长度
    
  3. 修复string_count的野指针问题
    不要返回栈上局部变量的地址,给行数统计值也分配堆内存:
    // 原错误代码:how_many[0] = &words;
    how_many[0] = malloc(sizeof(int));
    *how_many[0] = words;
    
    对应释放内存时,要先释放how_many[0]和how_many[1]指向的堆空间,再释放how_many本身,避免内存泄漏。
  4. 补全资源释放逻辑
    函数返回前记得释放所有申请的堆内存、关闭文件、释放mmap映射:
    • 写完文件后先调用munmap(map, st.st_size)释放内存映射
    • 遍历split数组释放每个字符串,再释放split本身
    • 释放temp_split、to_search、filename等malloc申请的内存
    • 最后调用fclose(stream)关闭文件流

修改完成后再执行删除FOO变量的操作,.bashrc文件会正确保留除目标行外的所有内容,不会再出现末尾重复文本的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 02:39:24