【问题标题】:The pointer changes the value of the address it points to指针改变它指向的地址的值
【发布时间】:2021-12-29 09:20:57
【问题描述】:

我希望pFirst 总是指向地址中的同一个地方。然而,看起来pFirst 与pCurrent 一起移动,即使该函数只进入了 Else 语句一次。

注意:代码正在创建一个链表。

void Push(T data) {
    ++_size;
    Data d = Data(data);
    if (_pCurrent != nullptr) _pCurrent->SetNext(&d);
    else _pFirst = &d;

    _pCurrent = &d;
}

【问题讨论】:

  • 指针&d在函数返回后无效,因为它指向一个局部变量。
  • 是的,d是本地创建的,所以函数结束后就不存在了,调试错误有点奇怪,因为程序在同一个地址初始化了一个新元素所以我没有立即理解到底发生了什么。
  • 是的,d是在本地创建的,所以函数结束后就不存在了 -- 你在发布问题之前是否理解这一点,或者刚刚在@评论之后interjay 制作完成了吗?
  • 我同时意识到(当我在调试中发表评论时)。这在调试器中相当混乱,因为它在同一地址初始化对象。
  • 在任何一种情况下,您都必须删除 &d 的使用,因为函数结束后指针无效。

标签: c++ pointers linked-list


【解决方案1】:

d是本地创建的,所以函数结束后就不存在了。调试错误有点奇怪,因为程序在同一个地址初始化了一个新元素,所以我没有立即明白到底发生了什么。

这是工作版本:

void Push(const T data) {

Data*d = new Data(data);
++_size;
if (_pCurrent != nullptr)
    _pCurrent->_pNext = d;
else
    _pFirst = d;
   _pCurrent = d;

}

【讨论】:

  • 在一个完全不相关的注释上:另见stackoverflow.com/questions/228783/…。以下划线开头后跟大写字母的符号(例如 _pFirst)在所有范围和情况下都是保留的。
  • _pFirst 是一个下划线后跟一个小写字母
  • 小挑剔:我不会先增加_size,以防new 失败。并且data 应该通过 const 引用传递,除非T 支持移动语义并且Data() 构造函数使用std::move() 来传输data 的内容。
  • 嗨,T 不支持 move ,它应该是 Const ,并且在我们确定在 List 中创建了新元素之后,_size 的增量应该是最明确的。很好的建议,谢谢。
【解决方案2】:

数据应该是一个静态变量。代码应该是这样的:

Data d;
void UpdateData(Data newData) {
    //Do something on d using newData;
}

void Push(T data) {
        ++_size;
        UpdateData(data);
        if (_pCurrent != nullptr)
            _pCurrent->_pNext = d;
        else
            _pFirst = d;
           _pCurrent = d;
    }

【讨论】:

  • 显然这段代码正在创建一个链表。您的解决方案将使列表中的所有节点都指向内存中的单个节点。那是行不通的。
  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。
猜你喜欢
  • 2020-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-11
  • 1970-01-01
相关资源
最近更新 更多