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

C语言char指针数组传参结果异常及strdup内存释放问题咨询

代码运行失败原因分析
  • 核心问题是二维指针数组传参类型不匹配:
    你在main函数中定义的char *list2[5][7]是二维char指针数组,数组名作为参数传递时,会退化为指向包含7个char*元素的数组的指针,类型为char* (*)[7],但你第二段代码的split函数形参写的是char **list2,二者是完全不同的指针类型,寻址逻辑完全不一致。
    当你在函数内访问list2[count2][count3]时,程序会按照char**的规则做内存偏移,拿到的是非法地址,触发内存访问错误,最终导致printf崩溃。同理list3的传参也存在相同的类型不匹配问题。
  • 补充:你第三版代码的split形参char* (*list2)[7], char*(*list3)[6]是正确的匹配类型,用这个形参声明就可以解决传参错误问题。
内存释放问题分析

你当前的释放方式完全错误:

  1. free(strdup(p))没有任何作用:strdup每次调用都会重新申请一块新的内存拷贝字符串,你这行代码等于新申请了一块内存、立刻释放,之前存在list2[count2][count3]里的那片strdup申请的内存完全没有被释放,会造成内存泄漏。
  2. 你之前直接在循环内free(list2[count2][count3])出错的原因是:你刚把strdup返回的地址存到数组里就立刻释放了,后续如果有任何代码访问list2对应的元素,都会访问野指针触发错误。
  3. 你尝试free(p)出错的原因是:p是strtok返回的指针,指向的是原list[count]字符串内部的地址,strtok只会修改原字符串插入\0做分割,不会申请堆内存,p指向的不是malloc类函数返回的堆地址,不需要也不能用free释放。

正确的释放方式

等整个程序完全使用完list2、list3存储的所有内容之后,遍历二维数组逐个释放元素即可,示例如下:

// 释放list2
for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 7; j++) {
        if (list2[i][j] != NULL) {
            free(list2[i][j]);
        }
    }
}
// 释放list3
for (int i = 0; i < size-7; i++) {
    for (int j = 0; j < 6; j++) {
        if (list3[i][j] != NULL) {
            free(list3[i][j]);
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 16:36:02