You need to enable JavaScript to run this app. Linux下g++运行C++代码报free(): invalid pointer,VS2019正常的问题排查
优惠活动
大模型
产品
解决方案
定价
更多

Linux下g++运行C++代码报free(): invalid pointer,VS2019正常的问题排查

跨平台运行报错的根本原因

这个*free(): invalid pointer*崩溃,本质是你写的堆内存释放逻辑完全搞混了内存归属,踩了C内存管理的红线。VS2019带的微软C运行时对非法内存操作管得很松,没第一时间崩;但Linux下g++用的glibc内存分配器校验特别严,只要发现你在释放根本不是自己申请的堆内存、野指针,就会直接终止程序生成core dump。

具体的错误点

  • swap操作把内存归属搞反了
    就拿rangbrk的执行流程说,比如输入是ls > out.txt,分词完的原始指针数组a里,存的是["ls", ">", "out.txt", NULL]这几个token,每个token都是之前new char[50]开的堆内存。
    函数里你新开了个长度刚好够存有效token的指针数组b,把ls的内容逐字拷贝到b[0]新开的堆内存里,设b[1]为NULL,再把out.txt的内容拷贝到输出文件名变量。
    这时候你做了个swap:把旧的a数组指针存到临时变量c,让a指向新的b数组,再让b指向原来的旧a数组。
    结果swap完你就开始循环:
    for(int i=0;i<x-1;i++)
    {
        delete [] b[i];
    }
    
    现在的b就是那个存了所有原始token的旧数组啊!你拿这个数组里存的指针去delete,删的是最开始存ls那块的堆内存——这块内存你只是把内容读出来拷贝去新数组了,根本不该在这时候删。更绝的是,新a数组里指向的那批字符串,是你在rangbrk里重新new出来的,你从头到尾没释放过这部分内存,直接造成内存泄漏。
  • 释放边界没算对,扫到野指针
    langbrk函数里,构建新的b数组时,你会跳过和<相关的两个元素,剩下的元素才会被赋值新开的堆内存。swap完成后,原来的旧a数组被赋值给变量b,你循环delete的边界没卡准,会扫到那些从来没赋值、也没被new过的野指针位置,直接对野指针执行delete[]——这种操作在Linux下百分百会被glibc抓到,直接抛错。
  • 藏得更深的越界问题
    main里你申请的指针数组a,长度刚好等于读到的token数,但你写完token之后直接往a[s]的位置写了个NULL,这个位置已经超出你申请的数组边界了,属于实打实的越界写,只是刚好没把程序搞崩而已。

为什么VS2019跑的时候啥事没有?
因为微软的MSVCRT运行时对内存的校验非常宽松,哪怕你提前释放、重复释放、甚至释放栈上的变量,很多时候都不会立刻报错。但Linux下glibc的ptmalloc会给每个堆块存校验标记,只要你free的时候传的指针不是合法堆块的起始地址,就立刻触发abort,生成core dump。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 23:27:04