为什么C语言中返回二级指针会出现未定义行为?
问题原因
主要有两个核心问题导致你遇到的情况:
- 栈内存悬垂引用(核心错误)
你在func函数内定义的list二维字符数组、l指针数组都是栈区局部变量,这类变量的生命周期仅和当前函数的栈帧绑定:当func执行完毕返回后,对应的栈帧会被操作系统回收释放,这部分内存的内容会被后续操作覆盖、或者直接标记为不可用。你返回的point二级指针本质是指向已经被释放的栈内存的野指针,后续对pointers的访问属于未定义行为,理论上可能出现任何结果:崩溃、乱码、随机值都属于正常情况。 - 输出格式不符合预期
就算暂时忽略栈内存释放的问题,你用printf("%d", *pointers[0])的写法本身也不会输出字符串:pointers[0]是指向第一个字符串首地址的字符指针,*pointers[0]是取首地址存储的第一个字符'a',用%d格式输出的就是字符'a'对应的ASCII码值,也就是你看到的97。
修复方案
如果要实现你的需求,可以把要返回的内存放在堆区,手动申请和释放,示例代码如下:
#include<stdio.h> #include<stdlib.h> #include<string.h> char ** func() { // 堆上申请二级指针数组 char ** point = malloc(2 * sizeof(char*)); // 每个元素也申请堆内存存字符串 point[0] = malloc(20 * sizeof(char)); point[1] = malloc(20 * sizeof(char)); strcpy(point[0], "a140"); strcpy(point[1], "3.14"); return point; } int main() { char ** pointers; pointers = func(); // 输出字符串用%s,直接传pointers[0]即可不需要解引用 printf("%s\n", pointers[0]); printf("%s\n", pointers[1]); // 手动释放堆内存避免泄漏 free(pointers[0]); free(pointers[1]); free(pointers); return 0; }
内容的提问来源于stack exchange,提问作者Evandro Filipe
相关产品推荐
相关产品推荐

