单指针能否在函数内初始化?给定create_smth(smth* s)原型如何创建返回smth变量
问题核心原因
C语言所有参数都是值传递,你传入的指针本身只是一个副本,函数内部修改指针的指向(也就是你写的s = malloc(...))不会对函数外部的原指针产生任何影响,这是你两次调用都出错的根本原因。
第一种调用报错原因
你定义smth* smth1=NULL;后调用函数,只是把smth1的值(也就是NULL)复制给了函数形参s,函数内部给s赋值为malloc返回的地址,仅修改了形参这个局部变量,外部的smth1还是NULL,后续你访问smth1的成员就会直接触发段错误,同时还会造成malloc的内存泄漏。
第二种调用报错原因
你定义的是栈上的smth smth1;,本身已经分配了内存,不需要再malloc。你把它的地址传给函数后,函数内部执行s = malloc(...),同样是修改了形参s的指向,相当于直接丢了原栈变量的地址。如果函数后续没有对原栈上的smth1做初始化,你访问它的未初始化成员也会触发段错误或逻辑异常。
单指针原型下的可行实现方案
如果必须严格使用题目给出的void create_smth(smth* s)原型,不修改函数签名,是可以实现需求的,但不能在函数内给s本身重新赋值,要直接对s指向的内存做初始化:
void create_smth(smth* s) { // 示例:假设smth结构体有num、ptr两个成员 s->num = 0; s->ptr = NULL; // 所有初始化操作直接操作s指向的内存即可,不要给s重新赋值 }
对应的正确调用方式只能用你写的第二种,要保证外部先分配好smth类型的内存,再把地址传进去:
// 栈上分配的场景 smth smth1; create_smth(&smth1); // 可正常运行 // 堆上分配的场景也兼容 smth* smth2 = malloc(sizeof(smth)); create_smth(smth2); // 使用完成后记得释放内存 free(smth2);
函数内分配内存的场景必须修改原型
如果需求是函数内部完成malloc分配内存、再把地址返回给调用方,那当前的单指针原型确实无法实现,必须修改为双指针:
// 修改后的函数原型 void create_smth(smth** s) { *s = malloc(sizeof(smth)); // 初始化操作 (*s)->num = 0; (*s)->ptr = NULL; }
对应的调用方式:
smth* smth1 = NULL; create_smth(&smth1); // 后续使用完成后记得释放 free(smth1);
总结
- 现有单指针原型本身没有问题,只是你的实现逻辑和调用方式不匹配:如果用单指针,就不能在函数内重新给指针赋值,要由调用方提前分配内存,函数只负责初始化。
- 如果必须要在函数内分配内存再返回,那确实需要双指针,当前原型满足不了这个需求,可以和导师确认需求的具体指向。
内容的提问来源于stack exchange,提问作者JamesTheProg
相关产品推荐
相关产品推荐

