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]是正确的匹配类型,用这个形参声明就可以解决传参错误问题。
内存释放问题分析
你当前的释放方式完全错误:
free(strdup(p))没有任何作用:strdup每次调用都会重新申请一块新的内存拷贝字符串,你这行代码等于新申请了一块内存、立刻释放,之前存在list2[count2][count3]里的那片strdup申请的内存完全没有被释放,会造成内存泄漏。- 你之前直接在循环内
free(list2[count2][count3])出错的原因是:你刚把strdup返回的地址存到数组里就立刻释放了,后续如果有任何代码访问list2对应的元素,都会访问野指针触发错误。 - 你尝试
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
相关产品推荐
相关产品推荐

