指针作为函数参数传递需要注意的问题

空指针作为函数参数

最近在复习C语言的知识,总算弄懂了指针作为函数参数传递的一些问题,比如下面这个经常会写的bug:

void func(char* q){
    q = (char*)malloc(100);
}
int main(){
    char* p = nullptr;
    func(p);
    //报错,段错误,因为此时的p没有被分配内存空间
    strcpy(p,"hello world");
    cout<<p<<endl;
    free(p);
    return 0;
}

原因就是,指针p作为函数参数传递的时候,传的是指针的值,即指针指向的内存地址,形参q接收了这个值,但是形参q自己的地址和p的地址不一样,因为q是在栈上临时分配的地址。即: p==q,但是&p != &q,所以在函数中使用malloc重新分配内存,赋值给p,主函数中的q并不会被改变,此时p!=q
所以如果函数的参数是一个指针,不要指望用该指针去申请动态内存,只能通过这个指针去改变其指向内存地址的内容。
上面代码的正确写法可以是如下写法,传递指针的引用,这样&q==&p,q和p就是同一个地址:

void func(char* &q){
    q = (char*)malloc(100);
}
int main(){
    char* p = nullptr;
    func(p);
    //正常,不会报错
    strcpy(p,"hello world");
    cout<<p<<endl;
    free(p);
    return 0;
}

也可以返回新分配的内存地址给主函数的p,因为此处的q是在堆上分配的内存,函数结束后不会被立即回收,所以可以返回,但是如果是栈上的临时变量就不可以被返回

char* func(char* q){
    q = (char*)malloc(100);
    return q;
}
int main(){
    char* p = nullptr;
    p = func(p);
    //正常,不会报错
    strcpy(p,"hello world");
    cout<<p<<endl;
    free(p);
    return 0;
}

还可以使用指向指针的指针来为p分配内存:

void func(char** q){
    *q = (char*)malloc(100);
}
int main(){
    char* p = nullptr;
    func(&p);
    //正常,不会报错
    strcpy(p,"hello world");
    cout<<p<<endl;
    free(p);
    return 0;
}

总而言之,指针作为参数时,不能在函数体中改变指针的内存地址,要不然,实参的拷贝(压入栈中),即形参改变了,而实参没有改变,会造成内存泄露并且还达不到分配内存的效果,容易出bug。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值