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

C++类实现链表报taking address of rvalue错误如何解决

报错原因

你遇到的报错核心是代码尝试获取右值(临时对象)的内存地址:

taking address of rvalue [-fpermissive]
   31 |     ListNode l = ListNode(2, &ListNode(4));

C中直接写ListNode(4)构造出的是临时对象,属于纯右值,它的生命周期仅持续到当前行表达式执行完毕,表达式结束后这个临时对象就会被系统自动销毁。如果把它的地址存到链表节点的next指针里,后续这个指针会变成悬空指针,指向已经被回收的无效内存,访问时会触发未定义行为(崩溃、脏数据等),因此编译器默认会直接拦截这种不合法的写法。
另外你用class实现链表和用struct实现没有本质区别,C
中struct默认成员访问权限是public,class默认是private,你已经把ListNode的成员都声明为public了,用法和struct完全一致,这个报错和你用class还是struct没有关系。

正确实现方案

根据你需要的节点生命周期,选对应写法即可:

  • 栈上静态分配:适合节点生命周期和当前作用域绑定的场景,不需要手动管理内存,注意被指向的节点要比持有它指针的节点先定义、后销毁
#include<iostream>
class ListNode {
public:
    int val;
    ListNode *next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode *next) : val(x), next(next) {}
};

int main(){
    // 先定义值为4的节点,它的生命周期贯穿整个main函数
    ListNode node4(4);
    // 再定义头节点,传入node4的地址是合法的,因为node4在l之后才会被销毁
    ListNode l(2, &node4);
    return 0;
}
  • 堆上动态分配:适合节点生命周期需要跨作用域的场景,需要手动管理内存,用完后要逐个delete节点避免内存泄漏
#include<iostream>
class ListNode {
public:
    int val;
    ListNode *next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode *next) : val(x), next(next) {}
};

int main(){
    // 在堆内存创建值为4的节点,生命周期直到手动调用delete才会结束
    ListNode* node4 = new ListNode(4);
    ListNode l(2, node4);

    // 链表使用完毕后释放堆内存
    delete node4;
    return 0;
}

注意:不要通过加-fpermissive编译选项强行绕过这个报错,临时对象销毁后指针指向的内存会被系统复用,后续访问会出现完全不可预期的错误。

内容的提问来源于stack exchange,提问作者Simon Rechermann

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 10:30:35